android 事件分發(fā)機(jī)制

安卓事件分發(fā)主要有以下 三個(gè) 方法

dispatchTouchEvent(MotionEvent ev) //用來(lái)進(jìn)行事件分發(fā)
onInterceptTouchEvent(MotionEvent ev) //判斷是否攔截事件(只存在viewGroup中)
onTouchEvent(MotionEvent ev) //處理點(diǎn)擊事件
手指觸摸屏幕首先進(jìn)入的是 Activity 的 disPatchTouchEvent 方法,
在方法中先判斷 ViewGroup 的 disPatchTouchEvent 方法,
在判斷 Activity 的 onTouchEvent 方法,
事件的順序是:
Activity 調(diào)用 PhomeWindow 的 superDisPatchTouchEvent 方法,
PhoneWindow 調(diào)用 DecorView 的 superDisPatchTouchEvent 方法,
DecorView 再調(diào)用 ViewGtoup 的 disPatchTouchEvent 方法,
這樣事件來(lái)到 ViewGroip 中。

在ViewGroup 中 disPatchTouchEvent 的事件分發(fā):

首先判斷 onInterceptTouchEvent 是否攔截
攔截:走自己的 onTouchEvent 方法
注意:ViewGroup 沒(méi)有重寫 onTouchEvent 方法,執(zhí)行的是 View 的方法
不攔截:走子 View 的 disPatchEvent 方法

在View 中 disPatchTouchEvent 的事件分發(fā)

判斷 view 是否可見(未被其他窗口遮蓋且未隱藏)
可見:如果設(shè)置了 toucheListener ,先響應(yīng) TouchListener.onTouch 方法,
否則執(zhí)行 onTOuchEvent 方法

事件分發(fā)結(jié)論

一個(gè)事件序列 從 手指觸摸屏幕 到 手指離開屏幕,在 這個(gè)過(guò)程中 產(chǎn)生的一系列事件,以 DOWN 事件開始,中間含有不定數(shù)的 MOVE 事件,以 UP 事件結(jié)束。

正常情況下,一個(gè)事件序列 只能被 一個(gè)View 攔截并且消耗。

某個(gè)View 一旦決定攔截,那么 這個(gè)事件序列 都將由它的 onTouchEvent 處理,并且它的onInterceptTouchEvent 不會(huì)再被調(diào)用。

某個(gè) View 一旦開始處理事件,如果它不消耗 ACTION_DOWN 事件(onTouchEvent 返回 false),那么同一事件序列中 的 其他事件 都不會(huì) 再 交給它處理,并且 重新交于 它的 父元素 處理(父元素 的 onTouchEvent 被調(diào)用)。

事件的 傳遞過(guò)程 是 由內(nèi)向外 的,即 事件 總是 先 傳遞給 父元素,然后 再由 父元素 分發(fā)給 子元素,通過(guò) requestDisallowInterceptTouchEvent 方法 可以在 子View 中 干預(yù) 父元素 的 事件分發(fā)過(guò)程,但 ACTION_DOWN 事件 除外。

ViewGroup 默認(rèn)不攔截 任何事件,即 onInterceptTouchEvent 默認(rèn)返回 false。View 沒(méi)有 onInterceptTouchEvent 方法,一旦 有 點(diǎn)擊事件傳遞給它,那么 它的 onTouchEvent 方法就會(huì)被調(diào)用。

View 的 onTouchEvent 方法 默認(rèn)會(huì)消耗事件(默認(rèn)返回 true),除非 它是 不可點(diǎn)擊的(clickable 和 longClickable同時(shí)為 false)。View 的 longClick 默認(rèn)為 false,clickable 要分情況,比如 Button 的 clickable 默認(rèn)為 true,TextView 的 clickable 默認(rèn) 為 false。

View 的 enable 屬性 不影響 onTouchEvent 的默認(rèn)返回值。哪怕 一個(gè) View 是 disable 狀態(tài)的,只要 它的 clickable 或者 longclickable 有一個(gè)為 true,那么 它的 onTouchEvent 方法就會(huì) 返回 true。

onClick 會(huì)響應(yīng) 的前提 是 當(dāng)前 View 是可點(diǎn)擊的,并且 收到了 ACTION_DOWN 和 ACTION_UP 事件,并且受 長(zhǎng)按事件 的 影響,當(dāng)長(zhǎng)按事件 返回 true 時(shí),onClick 不會(huì)相應(yīng)。

onLongClick 在ACTION_DOWN 里 判斷是否進(jìn)行相應(yīng),要執(zhí)行長(zhǎng)按事件,該 VIew 必須是 longClickAble 的,并且設(shè)置了 OnlongClickListener。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容