android onTouchEvent處理機制總結(jié)(必看)
項目中總會用到一些觸摸事件,每次使用都是百度各種資料,看各種大神的分析筆記。這次我自己總結(jié)下關(guān)于觸摸事件的一些知識點。一來可以讓自己對觸摸事件印象更加深刻,也給以后的項目做一個參考。最難理解的其實是onTouchEvent方法。
一、 概述
1.只有view,ViewGroup,Activity 具有事件分發(fā)和消費的功能。
2.Activity因為上最先接觸到觸摸事件,因此Activity沒有事件攔截方法。即沒有dispatchTouchEvent方法。
3.對于不能添加子控件的view,不能對事件進(jìn)行分發(fā)和攔截,它只有onTouchEvent事件。
二、三個方法
1.public boolean dispatchTouchEvent(MotionEvent ev)
當(dāng)觸摸事件發(fā)生的時候,首先會被當(dāng)前的activity進(jìn)行分發(fā),即當(dāng)前activity的dispatchTouchEvent方法會被執(zhí)行。
這個時候,該方法有三種返回的情況:
return false: 表明事件不會被進(jìn)行分發(fā)。事件會以冒泡的方式被傳遞給上層的view或activity的onTouchEvent方法進(jìn)行消費掉。
return true:表明該時間已經(jīng)被處理。事件會被當(dāng)前view或activity的dispatchTouchEvent給消費掉。不會再進(jìn)行傳遞,事件到此結(jié)束。
return super.dispatchTouchEvent(ev):表明該事件將會被分發(fā)。此時當(dāng)前View的onIntercepterTouchEvent方法會捕獲該事件,判斷需不需要進(jìn)行事件的攔截。
2.public boolean onInterceptTouchEvent(MotionEvent ev)
該方法用戶攔截被傳遞過來的事件,用于判斷被傳遞過來的事件是否需要被當(dāng)前的view進(jìn)行處理。
return false :不對事件進(jìn)行攔截,放行該事件。事件會被傳遞到當(dāng)前view的子控件中,由子控件中的dispatchTouchEvent方法進(jìn)行分發(fā)處理。
return true : 攔截該事件,將該事件交給當(dāng)前view的onTouchEvent方法進(jìn)行處理。
return super.inInterceptTouchEvent(ev):默認(rèn)攔截方式,和return true一樣。該事件會被攔截,將該事件交給當(dāng)前view的onTouchEvent方法進(jìn)行處理。(這里需要有一點說明,當(dāng)有兩個view。A view中有一個B view.點擊A.A中如果onInterceptTouchEvent()返回super.interceptTouchEvent(ev),則事件將會被A進(jìn)行攔截,交給A的onTouchEvent()進(jìn)行處理,如果點擊的是B,A中如果onInterceptTouchEvent()返回super.interceptTouchEvent(ev),則事件將不會被攔截,會被分發(fā)到子控件中)
3.public boolean onTouchEvent(MotionEvent event)
當(dāng)前的view把事件進(jìn)行了攔截,則事件則會被傳遞到該方法中
return false:表明沒有消費該事件,事件將會以冒泡的方式一直被傳遞到上層的view或Activity中的onTouchEvent事件處理。如果最上層的view或Activity中的onTouchEvent還是返回false。則該事件將消失。接下來來的一系列事件都將會直接被上層的onTouchEvent方法捕獲
return true: 表明消費了該事件,事件到此結(jié)束。
return super.onTouchEvent(event):默認(rèn)情況,和return false一樣。
驗證:
MainActivity FatherView ChildView中幾個方法都返回super.****TouchEvent(ev)
分析:
1、當(dāng)點擊屏幕。MainActivity 中的dispatchTouchEvent方法先執(zhí)行,打印MainActivity-dispatchTouchEvent-->ACTION_DOWN
2、因為返回的是super.dispatchTouchEvent(ev),所以事件ev將會被分發(fā),但是MainActivity中沒有onInterceptTouchEvent()方法,所以事件被傳遞到FatherView中的dispatchTouchEvent方法.打印FatherView-dispatchTouchEvent-->ACTION_DOWN
3、在FatherView中dispatchTouchEvent返回的是super.dispatchTouchEvent(ev),所有事件會被分發(fā)。FatherView中的onInterceptTouchEven()中的方法被執(zhí)行。打印FatherView-onInterceptTouchEven-->ACTION_DOWN
4、FatherView中的onInterceptTouchEven()返回的是super.onInterceptTouchEvent(ev)。在這里,(1)如果點擊的是屏幕中的ChildView。事件將不會被攔截,會被傳遞到ChildView中的dispatchTouchEvent方法中。(2)如果點擊的值FatherView則事件將會被攔截。FatherView中的onTouchEvent()方法將被執(zhí)行。以(1)為例,將打印ChildView-dispatchTouchEvent-->ACTION_DOWN。
5、ChildView中dispatchTouchEvent返回的是super.dispatchTouchEvent(ev),所有事件會被分發(fā)。打印ChildView-onInterceptTouchEvent-->ACTION_DOWN。
6、此時ChildView中onInterceptTouchEvent返回的是super.onInterceptTouchEvent(ev),,而且已經(jīng)沒有子控件了,所以事件將被攔截。打印ChildView-onTouchEvent-->ACTION_DOWN。
7、在childView中onTouchEvent()返回額是super.onTouchEvent(ev)。事件將不會被消耗,將以冒泡的方式傳遞到上層空間中的onTouchEvent(),此處上層空間中的onTouchEvent返回的都是super.onTouchEvent(ev)。所以講一次打印 Father-onTouchEvent-->ACTION_DOWN。 MainActivty-onTouchEvent-->ACTION_DOWN。
8、之后的事件動作,將不再被MainActivity分發(fā)到子view,直接被MainActivty中的onTouchEvent處理消耗。打印MainActivity-dispatchTouchEvent-->ACTION_UP,MainActivty-onTouchEvent-->ACTION_UP
MainActivity-dispatchTouchEvent-->ACTION_DOWN FatherView-dispatchTouchEvent-->ACTION_DOWN FatherView-onInterceptTouchEven-->ACTION_DOWN ChildView-dispatchTouchEvent-->ACTION_DOWN ChildView-onInterceptTouchEvent-->ACTION_DOWN。 ChildView-onTouchEvent-->ACTION_DOWN Father-onTouchEvent-->ACTION_DOWN。 MainActivty-onTouchEvent-->ACTION_DOWN MainActivity-dispatchTouchEvent-->ACTION_UP, MainActivty-onTouchEvent-->ACTION_UP
代碼
MainActivity.java
public class MainActivity extends Activity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate( savedInstanceState); setContentView(R.layout. activity_main); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub Log. i(TAG, "activity-onTouchEvent-->" + TouchEventUtil.getTouchAction(event.getAction())); return super.onTouchEvent( event); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log. i(TAG, "activity-dispatchTouchEvent-->" + TouchEventUtil.getTouchAction(ev.getAction())); return super.dispatchTouchEvent( ev); }
public class FatherView extends LinearLayout { private static final String TAG = "MainActivity"; public FatherView(Context context) { super( context); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log. i(TAG, "Father-dispatchTouchEvent-->" + TouchEventUtil.getTouchAction(ev.getAction())); return super.dispatchTouchEvent( ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log. i(TAG, "Father-onInterceptTouchEvent-->" + TouchEventUtil.getTouchAction(ev.getAction())); return super.onInterceptTouchEvent( ev); } @Override public boolean onTouchEvent(MotionEvent event ) { Log. i(TAG, "Father-onTouchEvent-->" + TouchEventUtil.getTouchAction(event.getAction())); return super.onTouchEvent( event); } }
public class ChildView extends LinearLayout { private static final String TAG = "MainActivity"; public ChildView(Context context) { super( context); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { Log. i(TAG, "Child-dispatchTouchEvent-->" + TouchEventUtil.getTouchAction(ev.getAction())); return super.dispatchTouchEvent( ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log. i(TAG, "Child-onInterceptTouchEvent-->" + TouchEventUtil.getTouchAction(ev.getAction())); return super.onInterceptTouchEvent( ev); } @Override public boolean onTouchEvent(MotionEvent event ) { Log. i(TAG, "Child-onTouchEvent-->" + TouchEventUtil.getTouchAction(event.getAction())); return super.onTouchEvent( event); } }
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width= "match_parent" android:layout_height= "match_parent" tools:context="${relativePackage}.${activityClass}" > <com.ethanlbb.toucheventtest.FatherView android:layout_width= "match_parent" android:layout_height= "match_parent" android:background= "@android:color/holo_blue_dark" android:gravity= "center" > <com.ethanlbb.toucheventtest.ChildView android:layout_width= "200dp" android:layout_height= "200dp" android:layout_gravity= "center" android:background= "#0000ff" > </com.ethanlbb.toucheventtest.ChildView > </com.ethanlbb.toucheventtest.FatherView > </RelativeLayout>
以上這篇android onTouchEvent處理機制總結(jié)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Android LayoutInflater加載布局詳解及實例代碼
這篇文章主要介紹了Android LayoutInflater加載布局詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02Android入門之TableLayout應(yīng)用解析(二)
這篇文章主要介紹了Android入門之TableLayout應(yīng)用,需要的朋友可以參考下2014-08-08android異步任務(wù)設(shè)計思詳解(AsyncTask)
AsyncTask在Android十分常用,那為什么如此常用呢,不用行不行呢,內(nèi)部又是怎么實現(xiàn)的呢,為什么Java的API中沒有這個類呢,看完本文后,你將會知道答案2014-02-02Android App在線程中創(chuàng)建handler的方法講解
這篇文章主要介紹了Android App在線程中創(chuàng)建handler的方法講解,文中同時講解了handler和線程的關(guān)系以及使用Handler時一些需要注意的地方,需要的朋友可以參考下2016-03-03