摘要:今天結合流程圖和代碼來對事件分發機制做一個總結,我自己起一個叫法就是個。返回就會把事件給父類的消費。以后事件不再交給這個。到這里事件分發就說的差不多了,我們這個比較簡單,但是不影響理解原理。
今天結合流程圖和代碼來對Android事件分發機制做一個總結,我自己起一個叫法就是“3個3”。
跟事件分發相關的主要有三個節點方法:
1.dispatchTouchEvent
2.onInterceptTouchEvent(這個只有ViewGroup有)
3.onTouchEvent
為了簡單扼要,Demo總共就三個研究對象,Activity/ViewGroup/View,從屬關系就是Activity中加載ViewGroup, ViewGroup中有一個View是Button,之所以用Button就是為了點擊事件。在Button點擊的時候看下三者事件分發的順序。
在Activity中, 主要就是添加幾個Log,在onTouchEvent中打印出MotionEvent事件,這里為了簡單主要關注
1.ACTION_DOWN 按下事件
2.ACTION_MOVE 移動事件
3.ACTION_UP 松開事件
@Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.w(Constants.TAG, "------------------------------------------"); Log.d(Constants.TAG, "MainActivity.dispatchTouchEvent"); return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { String eventString; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: eventString = "ACTION_DOWN"; break; case MotionEvent.ACTION_MOVE: eventString = "ACTION_MOVE"; break; case MotionEvent.ACTION_UP: eventString = "ACTION_UP"; break; default: eventString = "OTHER_EVENT"; break; } Log.d(Constants.TAG, "MainActivity.onTouchEvent: " + eventString); return super.onTouchEvent(event); }
在ViewGroup中,多了一個onInterceptTouchEvent方法。
@Override public boolean dispatchTouchEvent(MotionEvent ev) { Log.d(Constants.TAG, "ViewGroupCustom.dispatchTouchEvent"); return super.dispatchTouchEvent(ev); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { Log.d(Constants.TAG, "ViewGroupCustom.onInterceptTouchEvent"); return true; } @Override public boolean onTouchEvent(MotionEvent event) { String eventString; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: eventString = "ACTION_DOWN"; break; case MotionEvent.ACTION_MOVE: eventString = "ACTION_MOVE"; break; case MotionEvent.ACTION_UP: eventString = "ACTION_UP"; break; default: eventString = "OTHER_EVENT"; break; } Log.d(Constants.TAG, "ViewGroupCustom.onTouchEvent: " + eventString); return true; }
在View中方法和Activity中一樣:
@Override public boolean dispatchTouchEvent(MotionEvent event) { Log.d(Constants.TAG, "ViewCustom.dispatchTouchEvent"); return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { String eventString; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: eventString = "ACTION_DOWN"; break; case MotionEvent.ACTION_MOVE: eventString = "ACTION_MOVE"; break; case MotionEvent.ACTION_UP: eventString = "ACTION_UP"; break; default: eventString = "OTHER_EVENT"; break; } Log.d(Constants.TAG, "ViewCustom.onTouchEvent: " + eventString); return super.onTouchEvent(event); }
默認三個方法都是調用super的方法。
稍微總結下,涉及到三個3
1.第一個3就是三個研究對象:Activity/ViewGroup/View
2.第二個3就是三個方法:dispatchTouchEvent/onInterceptTouchEvent/onTouchEvent
3.第二個3就是每個方法都return3中狀態之一:super/true/false
接下來就是排列組合,事件分發就是在三個對象,三個方法,三個狀態之間進行各種排列組合,就組合成事件分發的多種狀態。接下來上一個很重要的圖,就是整體的事件分發流程圖:
上面這張流程圖很重要,今天這個解析就是圍繞著它轉了。下面就是分別把上面不同狀態進行詳細解釋。
先做個說明,在按鈕點擊的時候,我們就關注三個事件,ACTION_DOWN/ACTION_MOVE/ACTION_UP。
首先是三個對象的三個方法都不做更改,也就是都調用super,這就是默認狀態。這樣三個事件都會到按鈕的onTouchEvent,并且調用onClick回調方法。
接下來開始做點手腳,在Activity的dispatchTouchEvent中返回true狀態,這樣Activity就消費掉事件,不再往下傳給另外兩個對象,甚至也不調用自己的onTouchEvent方法。
Activity的dispatchTouchEvent中返回false,也是自己消費點,和上面返回true是一樣的。
接下來activity兩個方法保持默認,也就是super狀態,這樣事件就能傳遞到viewgroup了。然后對viewgroup動手腳,viewgroup有三個方法,所以狀態會多一點。首先在第一個方法dispatchTouchEvent返回true,這樣和acticity一樣的,自己直接消費掉,也不給自己的onTouchEvent。
如果把狀態改成false呢?這種情況也就類似于員工反了不干了,只能領導自己干,事件就會給activity的onTouchEvent消費,再之后的move和up事件不會再分發了,activity直接給自己的onTouchEvent消費。
接下來就是viewgroup的第二個方法onInterceptTouchEvent了。如果第一個方法默認返回super狀態,那么就會把事件給這個方法,viewgroup通過這個方法來告訴系統攔不攔截這個時間。返回true就是攔截,事件就會給自己的第三個方法onTouchEvent消費。如果onTouchEvent返回super或者false,那么事件就會給父類activity消費。之后事件不再傳給viewgroup,activity自己直接消費。這就類似于老板交給員工任務,員工沒完成好,老板以后就不交給這個員工了。
如果viewgroup的第二個方法返回false,表示自己不做攔截,那么事件就會傳遞給子類,這里就是button了。button就默認給自己的onTouchEvent消費掉。
如果第二個方法返回true表示攔截,事件就會給自己的onTouchEvent消費,onTouchEvent返回true,事件就是viewgroup自己消費,后續的事件也會給到viewgroup。
如果onTouchEvent返回false,事件就會給父類activity消費。之后事件不再傳給viewgroup,activity自己直接消費。
最后就是最后一個對象view,在這里是button。view只有兩個方法,沒有onInterceptTouchEvent。首先如果dispatchTouchEvent返回true,那么事件就直接消費掉了,不傳遞給自己的onTouchEvent方法。
dispatchTouchEvent返回false就會把事件給父類的onTouchEvent消費。以后事件不再交給這個view。
view的onTouchEvent方法如果返回true,那么事件就會自己消費點,并且不會調用onClick這個回調方法。
如果onTouchEvent返回false,那么事件就會交給父類,這個系列剩下的事件就不會再交給這個view了。
到這里事件分發就說的差不多了,我們這個Demo比較簡單,但是不影響理解原理。簡單坐下總結:
1.對于dispatchTouchEvent這個方法,返回true都是直接消費掉,不做其他傳遞。返回false就有點區別,對于activity是和true一樣直接消費掉,對于viewgroup和view就是把事件給父類的onTouchEvent消費。返回super就都是進行分發
2.onInterceptTouchEvent這個方法只有viewgroup有,返回true就是攔截,會把事件給到自己的onTouchEvent消費;返回false和返回super是一樣的,不攔截,分發給子view
3.onTouchEvent返回true就是消費掉事件了,如果返回false就傳遞給父類。返回super有點區別,對于viewgroup就和false一樣,傳遞給父類;對于view就會再接著往下傳遞,比如調用點擊回調等。
到這里就把事件分發說的差不多了,沒有放上源碼分析,我是覺得那樣內容就有點多,容易亂,如果面試的時候畫出上面的流程圖就差不多了。
如果本文對你有幫助,請點個贊哈,謝謝!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68881.html
摘要:事件被上層攔截時觸發。事件返回時直接指向了父的這一部分是不合理的,實際上它僅僅是給了父的一個返回值,父根據返回值來調用自身的。是根據的返回值來確定是調用子的還是自身的,并沒有將調用交給。 原文鏈接 簡簡單單講清楚android事件分發。 什么叫事件分發機制 ? 事件分發是:當發生了一個事件時,在屏幕上找到一個合適的控件來處理這個事件的過程。 因為一個界面上控件如此之多,發生一個事件后總...
摘要:下事件分發和消費事件前言中與事件相關的方法包括能夠響應的空間包括。事件分析事件分發事件發生時的方法會以隧道方式從根元素依次往下傳遞直到最內層子元素或在中間某一元素中由于某一條件停止傳遞將事件傳遞給最外層的 Android下Touch事件分發和消費事件 前言 Android中與touch事件相關的方法包括:dispatchTouchEvent(MotionEvent ev)、onInte...
閱讀 1565·2021-10-25 09:44
閱讀 2926·2021-09-04 16:48
閱讀 1543·2019-08-30 15:44
閱讀 2475·2019-08-30 15:44
閱讀 1731·2019-08-30 15:44
閱讀 2816·2019-08-30 14:14
閱讀 2964·2019-08-30 13:00
閱讀 2143·2019-08-30 11:09