點(diǎn)擊事件的傳遞規(guī)則
首先我們要明白這里要分析的對(duì)象就是MotionEvent,即點(diǎn)擊事件定踱。點(diǎn)擊事件分發(fā)的過程由三個(gè)很重要的方法共同完成:dispatchTouchEvent,
onInterceptTouchEvent,和onTouchEvent三個(gè)方法組成。
在分析事件分發(fā)機(jī)制之前叫榕,這里先給出一些結(jié)論
- 同一個(gè)時(shí)間序列是指手指接觸屏幕的那一刻起萤捆,到手指離開屏幕的那一刻結(jié)束叹哭,這個(gè)過程中闡釋的一系列事件,這個(gè)時(shí)間序列以Down事件開始帝火,中間含有數(shù)量不定的move事件溜徙,最終以u(píng)p時(shí)間結(jié)束。
- 正常情況下犀填,一個(gè)時(shí)間序列只能被一個(gè)View攔截且消耗蠢壹。
- 某個(gè)View一點(diǎn)決定攔截,那么這個(gè)事件序列都只能由它來處理九巡,并且它的onInterceptTouchEvent不會(huì)在被調(diào)用图贸。
- 某個(gè)View一旦開始處理事件,如果它不消耗Action_Down事件(onTouchEvent 返回了false)冕广,那么同一事件序列中的其他事件它都不會(huì)再交給它來處理疏日,并且事件將重新交給它的父元素去處理,即父元素的onTouchEvent會(huì)被調(diào)用撒汉。
- 如果View不消除ACTION_DOWN以外的其他事件沟优,那么這個(gè)點(diǎn)擊事件會(huì)消失,此時(shí)父元素的onTouchEvent并不會(huì)被調(diào)用睬辐,并且當(dāng)前View可以持續(xù)收到后續(xù)的事件挠阁,最終這些消失的電解事件會(huì)傳遞給Activity處理
事件分發(fā)機(jī)制的圖解(在分析的都是ACTION_DOWN事件)
圖解說明:
- 1:如果事件不中斷,整個(gè)事件的流向是一個(gè)U型圖
- 2:dispatchTouchEvent 和 onTouchEvent 一旦return true,事件就停止傳遞了
- dispatchTouchEvent 和 onTouchEvent return false的時(shí)候事件都回傳給父控件的onTouchEvent處理溉委。
- onInterceptTouchEvent方法中 return true就會(huì)交給自己的onTouchEvent的處理鹃唯,如果不攔截就是繼續(xù)往子控件往下傳
總結(jié):
- 對(duì)于 dispatchTouchEvent爱榕,onTouchEvent瓣喊,return true是終結(jié)事件傳遞。return false 是回溯到父View的onTouchEvent方法黔酥。
- ViewGroup 想把自己分發(fā)給自己的onTouchEvent藻三,需要攔截器onInterceptTouchEvent方法return true 把事件攔截下來洪橘。
- ViewGroup 的攔截器onInterceptTouchEvent 默認(rèn)是不攔截的,所以return super.onInterceptTouchEvent()=return false棵帽;
- View 沒有攔截器熄求,為了讓View可以把事件分發(fā)給自己的onTouchEvent,View的dispatchTouchEvent默認(rèn)實(shí)現(xiàn)(super)就是把事件分發(fā)給自己的onTouchEvent逗概。
關(guān)于ACTION_MOVE弟晚、ACTION_UP總結(jié)
對(duì)于ACTION_MOVE、ACTION_UP總結(jié):ACTION_DOWN事件在哪個(gè)控件消費(fèi)了(return true)逾苫, 那么ACTION_MOVE和ACTION_UP就會(huì)從上往下(通過dispatchTouchEvent)做事件分發(fā)往下傳卿城,就只會(huì)傳到這個(gè)控件,不會(huì)繼續(xù)往下傳铅搓,如果ACTION_DOWN事件是在dispatchTouchEvent消費(fèi)瑟押,那么事件到此為止停止傳遞,如果ACTION_DOWN事件是在onTouchEvent消費(fèi)的星掰,那么會(huì)把ACTION_MOVE或ACTION_UP事件傳給該控件的onTouchEvent處理并結(jié)束傳遞多望。不會(huì)再往下傳遞!