Android Touch事件傳遞機制通俗講解
在講正題之前我們講一段有關任務傳遞的小故事,拋磚迎玉下:
話說一家軟體公司,來一個任務,分派給了開發經理去完成:
開發經理拿到,看了一下,感覺好簡單,於是
開發經理:分派給了開發組長
開發組長:分派給了自己組員(程式設計師)
程式設計師:分派給了自己帶的實習生。
實習生:好苦逼,無法分派,怎麼辦啊?只能自己幹了
但是實習生能不能做好,有兩種情況了。
情況一:
實習生:經過一段時間的研究,琢磨,熬夜,奮鬥,死敲,皇天不負有心人啊,完成了。
後來又來一個類似的任務,也按著這樣傳遞下去了(開發經理->開發組長->程式設計師->實習生),又有實習生完成了。
情況二:
實習生:經過一段時間的研究,琢磨,就是毫無頭緒,無法完成,只能求教師傅(程式設計師)了。
程式設計師:啊,我怎麼沒留意就給實習生搞了,這任務好難啊,自己研究下,也沒有頭緒,沒辦法只能請求組長了。
開發組長:這任務不難啊,怎麼我底下的人都不會了,沒辦法,只能自己搞了,經過,一段時間,完成了,感想,以後要是又有跟這個很類似的任務,我就自己弄了,不給他們弄了。
後來又來一個類似的任務,傳遞是這樣的
開發經理:分派給開發組長
開發組長:啊,又是跟著上一個很類似的任務,我自己弄吧,沒過多久也完成了!
PS:以上就是一個任務傳遞的過程。上級一開始總會想把任務分派給自己的下屬去弄,然後任務一步一步去傳遞下去,最後由一個人去完成他,當然傳遞下去,最底下人不會,也會一步一步的回滾,又他上級去完成,如果又有一個類似的任務,那個節點不會的人就不會再傳遞給他,給他也不會弄。當然實現中,這些任務的傳遞也可能被分派人去攔截,比如說,開發組長本打算分派給程式設計師,突然他不想傳遞了,就半路攔截了下來。
而在我們android Touch事件傳遞機制跟這個很類似,思想差不多,有句話說,設計來源於生活。跟Touch事件有關的處理方法主要由三個:
//分派事件 public boolean dispatchTouchEvent(MotionEvent ev) //攔截事件 public boolean onInterceptTouchEvent(MotionEvent ev) //處理事件 public boolean onTouchEvent(MotionEvent event)
用他們的時候,我們只需要重寫一下,即可操作,這三個方法主要在三種類被呼叫,那三種類呢?
基類 | 例子類 | 擁有的方法 |
繼承Activity(activity類) | MainActivity(因專案而異) |
dispatchTouchEvent,onTouchEvent |
繼承ViewGroup(View容器) | RelativeLayout,FrameLayout,LinearLayout,AbsoluteLayout,ListView,ScrollView… |
dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent |
繼承View(View控制元件) | Button,EditText,TextView,ImageView…. |
dispatchTouchEvent,onTouchEvent |
而這三個方法的含義是什麼呢?
事件 | 含義 |
dispatchTouchEvent |
用來分派事件。 其中呼叫了onInterceptTouchEvent()和onTouchEvent(),一般不重寫該方法 |
onInterceptTouchEvent |
用來攔截事件。 ViewGroup類中的原始碼實現就是{return false;}表示不攔截該事件, 事件將向下傳遞(傳遞給其子View); 若手動重寫該方法,使其返回true則表示攔截,事件將終止向下傳遞, 事件由當前ViewGroup類來處理,就是呼叫該類的onTouchEvent()方法 |
onTouchEvent |
用來處理事件。 返回true則表示該View能處理該事件,事件將終止向上傳遞(傳遞給其父View); 返回false表示不能處理,則把事件傳遞給其父View的onTouchEvent()方法來處理 |
根據上面的小故事,我們用程式碼去實現一下:
我新建了四個類:MainActivity(開發經理),FirstFrameLayout(開發組長),SecondRelativeLayout(程式設計師),ThirdTextView(實習生)
在介面的層次關係如下圖:
我就好比我們前面的故事情況一,情況二那麼模擬下:
情況一
首先我們按照上面的故事情況一那樣,任務一級一級傳遞下去(將viewgroup的類的onInterceptTouchEvent都返回false),然後事件就會一直傳遞到,ThirdTextview,最後,我們把它的onTouchEvent返回ture(含義是實習生處理成功了)。我們點選藍色區域。我們看下日誌。
情況二
首先我們還是一級級傳遞下去(將viewgroup的類的onInterceptTouchEvent都返回false),然後是傳遞到ThirdTextview,我們將它的onTouchEvent返回false(含義是實習生處理失敗了),再講SecondRelativeLayout的onTouchEvent返回false(含義是程式設計師處理失敗了),最後講FirstFrameLayout的onTouchEvent返回true(含義是組長處理成功了)。我們點選藍色區域。我們看下日誌,如下圖。
注:上面兩種情況的日誌圖,紅色框代表第一個任務,黃色框代表第二個類似的任務。根據上圖日誌,我們畫下傳遞圖:
情況一事件傳遞圖:
情況二事件傳遞圖:
從上面兩張事件傳遞圖我們的出來一些結論:
1.事件是先有dispatchTouchEvent分派給下一級
2.要經過onInterceptTouchEvent是否需要攔截,不攔截傳遞給下一級,最終傳遞給view控制元件,
3.onTouchEvent方法中,在處理事件中,如果返回True,則表示能處理,傳遞將會終止。反著,不能,如果不能的話,這會返回上一級的onTouchEvent方法中,如果還是false,會一直到到上一層的onTouchEvent方法中。
好奇的我們會發現一個問題:圖二中的黃色線,沒有像紅色線那樣,先傳遞到最底層,然後再回滾回去,這是為什麼呢?
答:就如我們故事中,他都知道了,底下人都不會去做了,那麼他幹嘛還分派給他呢,他就會自己做了,直接給onTouchEvent ,這就是事件傳遞中的“記憶”功能。我們是手指點選藍色區域,Touch事件有兩個,第一個ACTION_DOWN,第二個ACTION_UP,第一個ACTION_DOWN事件向下傳遞到某View,它把事件繼續傳遞交給它的子View,它會記錄該事件是否被它下面的View給處理成功了,(怎麼能知道呢?如果該事件會再次被向上傳遞到我這裡來由我的onTouchEvent來處理,那就說明下面的View都沒能成功處理該事件);當第二個ACTION_UP事件向下傳遞到該View,該View的dispatchTouchEvent方法機會判斷,若上次的事件由下面的view成功處理了,那麼這次的事件就繼續交給下面的來處理,若上次的事件沒有被下面的處理成功,那麼這次的事件就不會向下傳遞了,該View直接呼叫自己的onTouchEvent方法來處理該事件。
PS:關於這“記憶”功能的資訊只在一系列事件完成之前有效,也就是從ACTION_DOWN事件開始,直到後續事件ACTION_MOVE,ACTION_UP結束後,“記憶”的資訊就會清除。也就是說如果某View處理ACTION_DOWN事件失敗了(onTouchEvent()返回false),那麼後續的ACTION_MOVE,ACTION_UP等事件就不會再傳遞到該View了,由其父View自己來處理。在下一次發生ACTION_DOWN事件的時候,還是會傳遞到該View的。
補充說明:
-》若在向下傳遞的過程中被攔截了,即onInterceptTouchEvent方法返回true,則事件將停止向下傳遞,直接由當前的onTouchEvent方法來處理,若處理成功則OK,若處理不成功,則事件會向上傳遞。
謝謝收看。
例項程式碼:http://download.csdn.net/detail/chenjie_920/8398413
相關文章
- Android觸控事件傳遞機制Android事件
- Android10_原理機制系列_事件傳遞機制Android事件
- Android中觸控事件的傳遞機制Android事件
- 【Android基礎】講講Android的事件分發機制Android事件
- Android之Handler訊息傳遞機制詳解Android
- 面試:講講 Android 的事件分發機制面試Android事件
- 用一張圖告訴你Android中的事件傳遞機制Android事件
- 【朝花夕拾】Android自定義View篇之(五)Android事件分發及傳遞機制AndroidView事件
- android事件分發機制詳解Android事件
- 通俗易懂講解TCP流量控制機制,瞭解一下TCP
- iOS 中的事件傳遞和響應機制 - 原理篇iOS事件
- iOS 中的事件傳遞和響應機制 - 實踐篇iOS事件
- iOS 中的事件傳遞和響應機制 – 實踐篇iOS事件
- Android事件分發機制Android事件
- Android Handler訊息傳遞機制:圖文解析工作原理Android
- android 訊息傳遞機制進階EventBus的深入探究Android
- Android事件分發機制,你瞭解過嗎?Android事件
- flutter 訊息傳遞機制Flutter
- Handler訊息傳遞機制
- 通俗講解 HTTPSHTTP
- 從事件驅動程式設計模型分析Handler訊息傳遞機制事件程式設計模型
- Android 事件分發機制原始碼詳解-最新 APIAndroid事件原始碼API
- 引數傳遞機制之JWTJWT
- Android 事件分發機制的理解Android事件
- Android的MotionEvent事件分發機制Android事件
- Android View 的事件體系 -- 事件分發機制AndroidView事件
- Js 的事件迴圈(Event Loop)機制以及例項講解JS事件OOP
- Spring事件機制詳解Spring事件
- Redis 事件機制詳解Redis事件
- 手機端html5觸屏事件(touch事件)HTML事件
- 淺談Android 事件分發機制(二)Android事件
- Android事件分發機制簡單理解Android事件
- Android事件分發機制三:事件分發工作流程Android事件
- React事件傳遞引數React事件
- Netty使用及事件傳遞Netty事件
- 淺談Android中的事件分發機制Android事件
- 通俗講解:PoW共識機制與以太坊的關係、Ghost協議 及 Casper PoS共識機制的變種協議
- touch事件與click事件區別事件
- Android 訊息機制詳解(Android P)Android