安卓事件分發(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。