之前對安卓觸摸事件分發只是大概的理解一下,現在已經有了更深入的理解,這篇博客要重新寫過,等過段事件重新寫
布局:Activity => ViewGroup => View
所有方法return super代表不做處理。
所有方法return true代表已消費,事件中止,不再傳遞。
dispatchTouchEvent()事件分發,return super為不處理(分發),true為不分發,false為不分發。
onInterceptTouchEvent()事件攔截,return super為不處理(不攔截),true為攔截,false為不攔截。
onTouchEvent()事件處理,return super為不處理(繼續傳遞),true為中止,false為繼續傳遞。
事件傳遞:
Activity.dispatchTouchEvent()
ViewGroup.dispatchTouchEvent()
ViewGroup.onInterceptTouchEvent()
View.dispatchTouchEvent()
如果調用了view.setOnTouchListener(listener),則先調用listener.onTouch()
View.onTouchEvent()
ViewGroup.onTouchEvent()
Activity.onTouchEvent()
+++++++++++++++++++++++++++++++++++++++++
想要進一步提升開發水平,事件分發機制是繞不開的。
網上也又各種博客分析源碼,我也是看得一半一半懂,其實都是Java源碼,慢慢看多幾遍還是能看懂的,沒有這個自信就不是程序員了。
這篇博客不寫源碼,不寫分析,僅僅是總結出Touch事件的分發流程。
需要知道的東西
-
dispatchTouchEvent
:分發事件。這個方法和事件分發機制密不可分,但這里不說這個。 -
onInterceptTouchEvent
:攔截事件。繼承此方法,返回true,表示攔截了此事件。 -
onTouchEvent
:監聽事件。繼承此方法,處理事件,返回true表示消費了此事件。 -
View
是沒有onInterceptTouchEvent
方法的
假設界面
這里假設我們有一個如下圖一樣的界面,在Activity中有一個ViewGroup1
,嵌套著ViewGroup2
,最上層是個View
。當然那些DecorView、FrameLayout什么的就不說了。看圖:
分發流程
分發流程用一個圖來說明,看:
下面的描述只需要看一遍,理解了就行,然后上面這個圖就會自動留在你的腦海中了,好簡單的圖。
- 用戶按下屏幕,滑動一下,再松開手,會發出一些列的事件:
DOWN-MOVE-MOVE...-UP
,這里主要說DOWN
事件。 - Activity首先會把
DOWN
事件分發給最底層的ViewGroup1
的onInterceptTouchEvent
方法。 -
onInterceptTouchEvent
,繼承并返回true,表示攔截此事件,不再傳遞下去;返回false,表示不攔截,事件直接傳遞給下一個ViewGroup
的onInterceptTouchEvent
方法。 -
onTouchEvent
,繼承并返回true,表示消費了此事件,不再傳遞下去;返回false,表示沒有消費,繼續傳遞下去給別的View處理。
注意:
如果一直沒有
View
消費DOWN
事件,則后面的MOVE
、UP
事件就不會再觸發了。
比如上面的例子,如果ViewGroup1
、ViewGrouip2
和View
的onTouchEvent
都返回false
的話,那么只會觸發DOWN
事件,后面的UP
事件將不會收到了。
如果某個
ViewGroup
消費了DOWN
事件,則后續的事件會把此ViewGroup
當初View
,也就是忽略它的onInterceptTouchEvent
。
比如上面的例子,如果ViewGroup2
的onTouchEvent
返回true,則后面的UP
事件會忽略ViewGroup2
的onInterceptTouchEvent
,會變成:ViewGroup1.onInterceptTouchEvent
-> ViewGroup2.onTouchEvent
。
實用的實踐例子
如有錯誤,歡迎指出,及時更正,不誤后來子弟。