作過android乃至作過UI開發的IT從業者大都接觸過這個名詞,顧名思義,即一系列事件的分發,這裏咱們將細緻的探討下android端的觸摸事件的分發機制。android
android事件分發,度娘上一抓一大把,爲何我還要寫這篇博客?這是個好問題,我看過很多相關的博文,也看過相應書籍對「事件分發」的解釋,但可能入門不久,以前一直沒領悟透徹,一些文章也沒讓我細緻的體悟到個鐘原因,疑問有:服務器
MotionEvent.ACTION_DOWN
事件返回true的話,以後的全部事件都沒法處理了?view
消耗了點擊事件,那麼以後的該系列事件就都由該view
消耗了?View#requestDisallowInterptTouchEvent(false)
又能將事件的處理權交出去呢?我帶着上面兩個問題去翻看了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
。
至此能夠對問題1,作出合理的解釋了。當子view不消費MotionEvent.ACTION_DOWN
事件的時候,那麼在MotionEvent.ACTION_DOWN處理結束後mFirstTouchTarget是爲null的
,而後該系列事件的move
等事件進入分發階段的時候,便會在圖一的2507和2508行的if校驗中進入2519行intercepted = true
始終攔截事件再也不分發出去。至於問題2,問題3,其實也大都涵蓋在上述分析中,聰明的小夥伴們,能夠自行總結一波code
親情推薦使用阿里雲服務器,實惠穩定 附贈優惠禮包自取: 阿里雲飛機票orm
本人才疏學淺,如有不足,或是胡言亂語之處,望海涵並加以斧正。cdn