android觸摸事件分發機制,曾困惑你個人地方

1.什麼是事件分發

作過android乃至作過UI開發的IT從業者大都接觸過這個名詞,顧名思義,即一系列事件的分發,這裏咱們將細緻的探討下android端的觸摸事件的分發機制。android

2.爲何要「炒冷飯」

android事件分發,度娘上一抓一大把,爲何我還要寫這篇博客?這是個好問題,我看過很多相關的博文,也看過相應書籍對「事件分發」的解釋,但可能入門不久,以前一直沒領悟透徹,一些文章也沒讓我細緻的體悟到個鐘原因,疑問有:服務器

  1. 爲何子view如果不在MotionEvent.ACTION_DOWN事件返回true的話,以後的全部事件都沒法處理了?
  2. 爲何一旦view消耗了點擊事件,那麼以後的該系列事件就都由該view消耗了?
  3. 在2的基礎上,爲何View#requestDisallowInterptTouchEvent(false)又能將事件的處理權交出去呢?

3.分析

我帶着上面兩個問題去翻看了ViewGroup#dispatchTouchEvent(MotionEvent ev)的源碼。函數

首先看下部分源碼:阿里雲

這段代碼,很顯然是事件攔截 onInterceptTouchEvent(ev)的觸發條件,故而,途中2507和2508兩行的條件是咱們須要關注的重點,當觸摸事件類型爲 ACTION_DOWN或者 mFirstTouchTarget != null時會進入是否攔截的判斷,這裏注意若是不知足上述條件時,第2519行代碼 intercepted = true,也就是說若是不是down事件的同時, mFirstTouchTarget == null那麼該次事件交由當前ViewGroup處理。那麼重點來了, mFirstTouchTarget是什麼?是如何賦值的?

接着看:spa

圖中3-28行爲接着上圖的代碼,這裏不難看出,3-7行,當事件沒取消不攔截的同時爲 MotionEvent.ACTION_DOWN,MotionEvent.ACTION_POINTER_DOWN, MotionEvent.ACTION_HOVER_MOVE事件的時候 dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)將事件分發給子view處理,如果子view的處理結果返回true則進入8-28行的邏輯並會 break跳出 for循環(敲黑板)重點來了,26行 newTouchTarget = addTouchTarget(child, idBitsToAssign);進入 addTouchTarget方法,即圖中39-44行,至此 mFirstTouchTarget的賦值咱們理出來了。

那麼有什麼用呢?接着看循環外面的邏輯:3d

從以前的分析,咱們得知,mFirstTouchTarget只有在存在子view消費了事件後,纔會 !=null,所以如果子view沒有消耗事件,則進入2643行,當前view去處理該事件。並最終在函數末尾 return handled

4 總結

至此能夠對問題1,作出合理的解釋了。當子view不消費MotionEvent.ACTION_DOWN事件的時候,那麼在MotionEvent.ACTION_DOWN處理結束後mFirstTouchTarget是爲null的,而後該系列事件的move等事件進入分發階段的時候,便會在圖一的2507和2508行的if校驗中進入2519行intercepted = true始終攔截事件再也不分發出去。至於問題2,問題3,其實也大都涵蓋在上述分析中,聰明的小夥伴們,能夠自行總結一波code

推薦

親情推薦使用阿里雲服務器,實惠穩定 附贈優惠禮包自取: 阿里雲飛機票orm

尾聲

本人才疏學淺,如有不足,或是胡言亂語之處,望海涵並加以斧正。cdn

相關文章
相關標籤/搜索