安卓Touch事件的分發流程

之前對安卓觸摸事件分發只是大概的理解一下,現在已經有了更深入的理解,這篇博客要重新寫過,等過段事件重新寫

布局: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什么的就不說了。看圖:

界面大致布局.png

分發流程

分發流程用一個圖來說明,看:

事件分發流程.png

下面的描述只需要看一遍,理解了就行,然后上面這個圖就會自動留在你的腦海中了,好簡單的圖。

  • 用戶按下屏幕,滑動一下,再松開手,會發出一些列的事件:DOWN-MOVE-MOVE...-UP,這里主要說DOWN事件。
  • Activity首先會把DOWN事件分發給最底層的ViewGroup1onInterceptTouchEvent方法。
  • onInterceptTouchEvent,繼承并返回true,表示攔截此事件,不再傳遞下去;返回false,表示不攔截,事件直接傳遞給下一個ViewGrouponInterceptTouchEvent方法。
  • onTouchEvent,繼承并返回true,表示消費了此事件,不再傳遞下去;返回false,表示沒有消費,繼續傳遞下去給別的View處理。

注意:

如果一直沒有View消費DOWN事件,則后面的MOVEUP事件就不會再觸發了。

比如上面的例子,如果ViewGroup1ViewGrouip2ViewonTouchEvent都返回false的話,那么只會觸發DOWN事件,后面的UP事件將不會收到了。

如果某個ViewGroup消費了DOWN事件,則后續的事件會把此ViewGroup當初View,也就是忽略它的onInterceptTouchEvent

比如上面的例子,如果ViewGroup2onTouchEvent返回true,則后面的UP事件會忽略ViewGroup2onInterceptTouchEvent,會變成:ViewGroup1.onInterceptTouchEvent -> ViewGroup2.onTouchEvent

實用的實踐例子

禁止滑動的ViewPager

如有錯誤,歡迎指出,及時更正,不誤后來子弟。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容