Android 事件分發流程30分鐘掌握

touch事件:

touch事件分發只有兩個主角:

ViewGroup 和View。Activity 的Touch事件實際上是調用ViewGroup的Touch事件,可以直接當成ViewGroup處理。
ViewGroup的相關事件有三個:onInterceptTouchEvent ,dispatchTouchEvent,onTouchEvent
View的相關事件有兩個:dispachTouchEvent,onTouchEvent
1.Touch事件分發中只有兩個主角:ViewGroup和View。ViewGroup包含onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent三個相關事件。View包含dispatchTouchEvent、onTouchEvent兩個相關事件。其中ViewGroup又繼承於View。
2.ViewGroup和View組成了一個樹狀結構,根節點爲Activity內部包含的一個ViwGroup。
3.觸摸事件由Action_Down、Action_Move、Aciton_UP組成,其中一次完整的觸摸事件中,Down和Up都只有一個,Move有若干個,可以爲0個。
4.當Acitivty接收到Touch事件時,將遍歷子View進行Down事件的分發。ViewGroup的遍歷可以看成是遞歸的。分發的目的是爲了找到真正要處理本次完整觸摸事件的View,這個View會在onTouchuEvent結果返回true。
5.當某個子View返回true時,會中止Down事件的分發,同時在ViewGroup中記錄該子View。接下去的Move和Up事件將由該子View直接進行處理。由於子View是保存在ViewGroup中的,多層ViewGroup的節點結構時,上級ViewGroup保存的會是真實處理事件的View所在的ViewGroup對象:如ViewGroup0-ViewGroup1-TextView的結構中,TextView返回了true,它將被保存在ViewGroup1中,而ViewGroup1也會返回true,被保存在ViewGroup0中。當Move和UP事件來時,會先從ViewGroup0傳遞至ViewGroup1,再由ViewGroup1傳遞至TextView。
6.當ViewGroup中所有子View都不捕獲Down事件時,將觸發ViewGroup自身的onTouch事件。觸發的方式是調用super.dispatchTouchEvent函數,即父類View的dispatchTouchEvent方法。在所有子View都不處理的情況下,觸發Acitivity的onTouchEvent方法。
7.onInterceptTouchEvent有兩個作用:1.攔截Down事件的分發。2.中止Up和Move事件向目標View傳遞,使得目標View所在的ViewGroup捕獲Up和Move事件。

在這裏插入圖片描述
在這裏插入圖片描述

對照上圖能讀懂以下log,基本上了解了事件的傳遞流程

ViewGroupA - ViewGroupB - View (默認返回false)

我們先不修改任何返回值,只是點擊一下View,然後看Log會怎樣記錄我們的操作和程序響應。點擊View後log:

01-06 10:01:11.807 30119 30119 D TestEvent: ViewGroupA dispatchTouchEvent :ACTION_DOWN
01-06 10:01:11.807 30119 30119 D TestEvent: ViewGroupA onInterceptTouchEvent :ACTION_DOWN
01-06 10:01:11.807 30119 30119 D TestEvent: ViewGroupB dispatchTouchEvent :ACTION_DOWN
01-06 10:01:11.807 30119 30119 D TestEvent: ViewGroupB onInterceptTouchEvent :ACTION_DOWN
01-06 10:01:11.807 30119 30119 D TestEvent: View dispatchTouchEvent :ACTION_DOWN
01-06 10:01:11.808 30119 30119 D TestEvent: View onTouchEvent :ACTION_DOWN
01-06 10:01:11.808 30119 30119 D TestEvent: ViewGroupB onTouchEvent :ACTION_DOWN
01-06 10:01:11.809 30119 30119 D TestEvent: ViewGroupA onTouchEvent :ACTION_DOWN

返回值都爲false
默認不處理:
ViewGroupA dispatchTouchEvent - >onInterceptTouchEvent ->ViewGroupB dispatchTouchEvent ->onInterceptTouchEvent ->View dispatchTouchEvent ->onTouchEvent (View dispatchTouchEvent向上)–>onTouchEvent (ViewGroupB dispatchTouchEvent向上)–>onTouchEvent (ViewGroupA)

ViewGroupA ()onInterceptTouchEvent()方法返回true: 直接返回給了ViewGroupA 的onTouchEvent直接處理了事件 如果viewGroupA 的onTouchEvent 返回true 則事件處理掉,如果false 則不處理事件

01-06 10:18:29.824 31192 31192 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_DOWN
01-06 10:18:29.824 31192 31192 D TestEvent: ViewGroupA onInterceptTouchEvent :true:ACTION_DOWN
01-06 10:18:29.824 31192 31192 D TestEvent: ViewGroupA onTouchEvent ::ACTION_DOWN

ViewGroupB ()onInterceptTouchEvent()方法返回true: 事件直接到viewGropB 的onTouchEvent 如果(viewGropB onTouchEvent)返回false,則分發給ViewGropA 的onTouchEvent

01-06 10:20:18.518 31338 31338 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_DOWN
01-06 10:20:18.518 31338 31338 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_DOWN
01-06 10:20:18.518 31338 31338 D TestEvent: ViewGroupB dispatchTouchEvent ::ACTION_DOWN
01-06 10:20:18.518 31338 31338 D TestEvent: ViewGroupB onInterceptTouchEvent :true:ACTION_DOWN
01-06 10:20:18.518 31338 31338 D TestEvent: ViewGroupB onTouchEvent ::ACTION_DOWN
01-06 10:20:18.519 31338 31338 D TestEvent: ViewGroupA onTouchEvent ::ACTION_DOWN

ViewGroupA onTouchEvent() 返回true :

01-06 10:26:01.576 31732 31732 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_DOWN
01-06 10:26:01.576 31732 31732 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_DOWN
01-06 10:26:01.576 31732 31732 D TestEvent: ViewGroupB dispatchTouchEvent ::ACTION_DOWN
01-06 10:26:01.576 31732 31732 D TestEvent: ViewGroupB onInterceptTouchEvent ::ACTION_DOWN
01-06 10:26:01.577 31732 31732 D TestEvent: View dispatchTouchEvent ::ACTION_DOWN
01-06 10:26:01.577 31732 31732 D TestEvent: View onTouchEvent ::ACTION_DOWN
01-06 10:26:01.578 31732 31732 D TestEvent: ViewGroupB onTouchEvent ::ACTION_DOWN
01-06 10:26:01.578 31732 31732 D TestEvent: ViewGroupA onTouchEvent :true:ACTION_DOWN

01-06 10:26:01.660 31732 31732 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_UP
01-06 10:26:01.660 31732 31732 D TestEvent: ViewGroupA onTouchEvent :true:ACTION_UP

ViewGroupB onTouchEvent() 返回true : 事件到ViewGroupB onTouchEVent 事件就不傳遞了。

01-06 10:29:10.538 31931 31931 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_DOWN
01-06 10:29:10.538 31931 31931 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_DOWN
01-06 10:29:10.539 31931 31931 D TestEvent: ViewGroupB dispatchTouchEvent ::ACTION_DOWN
01-06 10:29:10.539 31931 31931 D TestEvent: ViewGroupB onInterceptTouchEvent ::ACTION_DOWN
01-06 10:29:10.539 31931 31931 D TestEvent: View dispatchTouchEvent ::ACTION_DOWN
01-06 10:29:10.539 31931 31931 D TestEvent: View onTouchEvent ::ACTION_DOWN
01-06 10:29:10.540 31931 31931 D TestEvent: ViewGroupB onTouchEvent :true:ACTION_DOWN

01-06 10:29:10.632 31931 31931 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_UP
01-06 10:29:10.632 31931 31931 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_UP
01-06 10:29:10.632 31931 31931 D TestEvent: ViewGroupB dispatchTouchEvent ::ACTION_UP
01-06 10:29:10.632 31931 31931 D TestEvent: ViewGroupB onTouchEvent :true:ACTION_UP

在看一下ViewGroupA 中分發事件(dispatchTouchEvent)返回true 的結果:

01-06 10:31:37.876 32111 32111 D TestEvent: ViewGroupA dispatchTouchEvent :true:ACTION_DOWN

01-06 10:31:38.063 32111 32111 D TestEvent: ViewGroupA dispatchTouchEvent :true:ACTION_UP

所有事件都被攔截

在看一下ViewGroupB 中分發事件(dispatchTouchEvent)返回true 的結果:

01-06 10:32:42.881 32226 32226 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_DOWN
01-06 10:32:42.881 32226 32226 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_DOWN
01-06 10:32:42.882 32226 32226 D TestEvent: ViewGroupB dispatchTouchEvent :true:ACTION_DOWN

01-06 10:32:42.956 32226 32226 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_UP
01-06 10:32:42.956 32226 32226 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_UP
01-06 10:32:42.956 32226 32226 D TestEvent: ViewGroupB dispatchTouchEvent :true:ACTION_UP

View 的onTouchEvent 返回true:

01-06 11:11:46.792  2387  2387 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_DOWN
01-06 11:11:46.793  2387  2387 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_DOWN
01-06 11:11:46.793  2387  2387 D TestEvent: ViewGroupB dispatchTouchEvent ::ACTION_DOWN
01-06 11:11:46.793  2387  2387 D TestEvent: ViewGroupB onInterceptTouchEvent ::ACTION_DOWN
01-06 11:11:46.793  2387  2387 D TestEvent: View dispatchTouchEvent ::ACTION_DOWN
01-06 11:11:46.793  2387  2387 D TestEvent: View onTouchEvent :true:ACTION_DOWN

01-06 11:11:46.906  2387  2387 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_UP
01-06 11:11:46.906  2387  2387 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_UP
01-06 11:11:46.906  2387  2387 D TestEvent: ViewGroupB dispatchTouchEvent ::ACTION_UP
01-06 11:11:46.906  2387  2387 D TestEvent: ViewGroupB onInterceptTouchEvent ::ACTION_UP
01-06 11:11:46.906  2387  2387 D TestEvent: View dispatchTouchEvent ::ACTION_UP
01-06 11:11:46.906  2387  2387 D TestEvent: View onTouchEvent :true:ACTION_UP

view 的dispatchTouchEvent 返回true:

01-06 11:13:03.685  2649  2649 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_DOWN
01-06 11:13:03.685  2649  2649 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_DOWN
01-06 11:13:03.685  2649  2649 D TestEvent: ViewGroupB dispatchTouchEvent ::ACTION_DOWN
01-06 11:13:03.685  2649  2649 D TestEvent: ViewGroupB onInterceptTouchEvent ::ACTION_DOWN
01-06 11:13:03.685  2649  2649 D TestEvent: View dispatchTouchEvent :true:ACTION_DOWN

01-06 11:13:03.726  2649  2649 D TestEvent: ViewGroupA dispatchTouchEvent ::ACTION_UP
01-06 11:13:03.727  2649  2649 D TestEvent: ViewGroupA onInterceptTouchEvent ::ACTION_UP
01-06 11:13:03.727  2649  2649 D TestEvent: ViewGroupB dispatchTouchEvent ::ACTION_UP
01-06 11:13:03.727  2649  2649 D TestEvent: ViewGroupB onInterceptTouchEvent ::ACTION_UP
01-06 11:13:03.727  2649  2649 D TestEvent: View dispatchTouchEvent :true:ACTION_UP
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章