本文粗略解析下事件分發機制,後續會分析下源碼,但願可以幫助到你們解惑一二。函數
從一個例子提及cdn
在實踐中,大多數須要瞭解事件分發機制的可能就是滑動衝突了,須要瞭解何時到底誰應該處理這個事件,先來看個例子,當咱們點擊區域Viewblog
假如ViewGroup和View都默認不處理事件,不復寫對應函數事件
因爲onTouchEvent中返回了false,同時也就表明着不關心本次事件(我不關心此次手勢,不要來找我了),後續的MOVE,UP事件也不會傳遞進來源碼
假設View是須要處理事件,好比是Button之類的View,默認是可點擊的it
注意上述的前提是ViewGroup不會對此事件進行攔截,由於在DOWN事件傳遞到View的ontouchEvent以前,ViewGroup是有一次攔截機會的,若是ViewGroup的onInterceptTouchEvent返回false,則不攔截,可是注意下一次的MOVE、UP等事件仍是會走ViewGroup攔截的判斷,可根據邏輯進行攔截處理,若是沒有攔截,可是View的ontouchEvent返回了false,也就表示下面沒有View是願意處理這個事件的,那麼這個燙手的山芋(事件)仍是會回到ViewGroup的ontouchEvent中io
同時可見DOWN事件的返回值,其實就是表示着View自己對本次事件處理的意願如何,True則表明着願意處理該事件,false則表明不關心本次事件class
假如ViewGroup在DOWN事件中,攔截了事件onInterceptTouchEvent返回了true,那麼此時事件直接轉到ViewGroup的ontouchEvent中,後續的MOVE、UP事件也會交給ViewGroup處理,View是沒有機會處理到事件的,即便此時調用requestDisallowInterceptTouchEvent也是無效的request
假如ViewGroup在DOWN事件中沒有攔截事件,可是在MOVE中卻對事件進行了攔截處理,好比相似如ScrollView同樣,是能夠對其中的View進行點擊處理的,可是在滑動時,ScrollView須要處理本身的邏輯,這時候就在MOVE中攔截了事件lazyload
同一時間序列事件是指以down事件開始,中間含有數量不定的move事件,最終以up事件結束。
各個View的onTouchEvent方法對DOWN事件的處理,表明了該View對以此DOWN開始的整個手勢事件的處理意願,True表明須要處理這次事件,false則表示不關心,事件會回傳到上層View的ontouchEvent中
若是ViewGroup一旦決定攔截一個事件,也就是onInterceptTouchEvent返回True,那麼後續的同一時間序列事件將會被默認攔截,不會再調用onInterceptTouchEvent方法,後續事件會交給ontouchEvent進行處理
事件一旦交給一個View處理,那麼它就必須消耗掉,不然同一事件序列中剩下的事件就再也不交給他來處理了,若是ontouchEvent中返回false,那麼後續事件不會再傳遞進來
若是ViewGroup攔截了一個半路的事件(好比,MOVE),這個事件將會被系統變成一個CANCEL事件,並傳遞給以前處理該手勢(gesture)的子View,並且不會再傳遞(不管是被攔截的MOVE仍是系統生成的CANCEL)給ViewGroup的onTouchEvent方法。只有再到來的事件纔會傳遞到ViewGroup的onTouchEvent方法中。