Android View事件分發(fā)機(jī)制(一)

在Android中,View的事件分發(fā)機(jī)制是非常重要的知識(shí)體系,掌握View的事件分發(fā)機(jī)制對(duì)我們以后的自定義View和處理View的滑動(dòng)沖突等問題有很大的幫助;
我們這里主要分析的對(duì)象就是MotionEvent,即點(diǎn)擊事件,所謂的點(diǎn)擊事件分發(fā)就是對(duì)MotionEvent事件的分發(fā)過程。點(diǎn)擊事件的分發(fā)過程由三個(gè)非常重要的方法共同來完成:
1、dispatchTouchEvent:用來進(jìn)行事件的分發(fā),如果事件能夠傳遞給當(dāng)前View,那么此方法一定會(huì)調(diào)用;
2、onInterceptTouchEvent:用來判斷是否攔截某個(gè)事件;如果當(dāng)前View攔截了某個(gè)事件,那么在同一個(gè)事件序列當(dāng)中,此方法不會(huì)再次調(diào)用;
3、onTouchEvent:用來處理響應(yīng)點(diǎn)擊事件;
注:子View中是沒有onInterceptTouchEvent方法的,因?yàn)閂iew已經(jīng)是最底層了,無須再向下傳遞了,只有ViewGroup當(dāng)中有onInterceptTouchEvent方法;
接下來我們就用一個(gè)實(shí)例來說明一下事件的傳遞過程,首先我們創(chuàng)建一個(gè)布局由Activity、ViewGroup(LinearLayout)、View(TextView)三層控件組成,然后我們點(diǎn)擊View(TextView)來看一下View的事件傳遞流程:
log日志輸出如下:

 Activity____dispatchTouchEvent
 ViewGroup___dispatchTouchEvent
 ViewGroup___onInterceptTouchEvent
 View________dispatchTouchEvent
 View________onTouchEvent
 ViewGroup___onTouchEvent
 Activity____onTouchEvent

通過我們測(cè)試的輸出日志我們可以看到(測(cè)試中我們默認(rèn)對(duì)事件均不處理),在收到一個(gè)點(diǎn)擊事件后,最外層的Activity首先收到,執(zhí)行Activity的dispatchTouchEvent開始事件傳遞,然后傳遞給ViewGroup的dispatchTouchEvent,ViewGroup的dispatchTouchEvent收到后,調(diào)用ViewGroup的onInterceptTouchEvent,詢問是否要進(jìn)行事件攔截,然后不攔截繼續(xù)向下傳遞,傳遞給View的dispatchTouchEvent,View的dispatchTouchEvent收到事件后默認(rèn)調(diào)用View的onTouchEvent方法,即開始事件的處理,默認(rèn)不處理,然后向上傳遞給ViewGroup的onTouchEvent,ViewGroup的onTouchEvent也是默認(rèn)不處理,最后傳遞給Activity的onTouchEvent來進(jìn)行處理;
接下來我們來看一下上例當(dāng)中的事件傳遞圖


點(diǎn)擊事件傳遞流程圖

上圖清晰的展示出了在我們默認(rèn)不做任何處理的情況下,點(diǎn)擊事件傳遞的整個(gè)事件鏈,最外層的控件先收到點(diǎn)擊事件然后一層一層向下傳遞,傳遞到最底層后開始事件的處理,最底層的控件先開始事件處理,然后一層一層向上傳遞;因此我們可以得到結(jié)論:
1、事件的傳遞 由外向內(nèi)
2、事件的處理 由內(nèi)向外
接下來我們來舉更多的例子,把各種情況都考慮進(jìn)去,來開一下點(diǎn)擊事件是如何傳遞的,以便讓大家徹底了解View的事件傳遞機(jī)制;

情況1:View的dispatchTouchEvent返回true(攔截事件傳遞)

log輸出:

 Activity____dispatchTouchEvent
 ViewGroup___dispatchTouchEvent
 ViewGroup___onInterceptTouchEvent
 View________dispatchTouchEvent

圖示:

情況2

可以看到事件從外向內(nèi)傳遞,dispatchTouchEvent負(fù)責(zé)傳遞事件,當(dāng)傳遞到最里層View的dispatchTouchEvent,如果我們返回true,則表示結(jié)束傳遞消費(fèi)該事件;所有View的onTouchEvent均不再執(zhí)行;
結(jié)論:dispatchTouchEvent返回true將會(huì)直接消費(fèi)該事件,并且中斷事件傳遞,onTouchEvent方法也不會(huì)被調(diào)用

情況2:ViewGroup的onInterceptTouchEvent返回true攔截傳遞

log輸出:

 Activity____dispatchTouchEvent
 ViewGroup___dispatchTouchEvent
 ViewGroup___onInterceptTouchEvent
 ViewGroup___onTouchEvent
 Activity____onTouchEvent

圖示:

情況2

可以看到ViewGroup的onInterceptTouchEvent返回true表示攔截事件傳遞,事件將不會(huì)再向下傳遞,并且會(huì)調(diào)用ViewGroup的onTouchEvent來響應(yīng)處理事件,如果ViewGroup的onTouchEvent默認(rèn)不處理事件,將會(huì)繼續(xù)向上調(diào)用Activity的onTouchEvent來處理事件;
結(jié)論:onInterceptTouch返回true表示攔截事件傳遞,并調(diào)用自身的onTouchEvent方法,下層控件將不會(huì)再收到相應(yīng)事件;

情況3:View的dispatchTouchEvent返回false

log輸出:

 Activity____dispatchTouchEvent
 ViewGroup___dispatchTouchEvent
 ViewGroup___onInterceptTouchEvent
 View________dispatchTouchEvent
 ViewGroup___onTouchEvent
 Activity____onTouchEvent

圖示:


情況3

可以看到View的dispatchTouchEvent返回false表示我不響應(yīng)該事件,并回調(diào)父控件的onTouchEvent方法;
結(jié)論:dispatchTouchEvent返回false表示不攔截并且不響應(yīng)該事件,并回調(diào)父控件的onTouchEvent方法讓父控件去處理事件;

情況4:View的onTouchEvent返回true

log輸出:

 Activity____dispatchTouchEvent
 ViewGroup___dispatchTouchEvent
 ViewGroup___onInterceptTouchEvent
 View________dispatchTouchEvent
 View________onTouchEvent

圖示:

情況4

可以看到當(dāng)View的onTouchEvent方法返回true時(shí)就表示要消費(fèi)該事件,并停止傳遞;
結(jié)論:onTouchEvent返回true表示消費(fèi)該事件,同時(shí)終止事件傳遞;
綜上所有情況總結(jié):
1、dispatchTouchEvent 返回 true 表示消費(fèi)該事件,終止事件傳遞,所有的onTouchEvent方法都不會(huì)執(zhí)行;
2、dispatchTouchEvent 調(diào)用 super 向下傳遞事件,調(diào)用子View的dispatchTouchEvent,若沒有子View了,調(diào)自身的onTouchEvent方法;
3、dispatchTouchEvent 返回 false 表示終止事件傳遞,不再向下傳遞事件,并且不會(huì)調(diào)用自身的onTouchEvent方法,而是向上調(diào)用父控件的onTouchEvent方法;
4、onInterceptTouchEvent 返回 true 表示攔截事件,不會(huì)再向下傳遞事件,然后調(diào)用自身的onTouchEvent方法;
5、onInterceptTouchEvent 返回 false/super 表示不攔截事件,繼續(xù)向下傳遞事件;
6、onTouchEvent 返回 true 表示消費(fèi)該事件,事件傳遞終止;
7、onTouchEvent 返回 false/super 不處理,事件繼續(xù)向上傳遞;
有了以上總結(jié)之后,Android中的View點(diǎn)擊事件傳遞流程已經(jīng)非常清晰了,因此我畫了一個(gè)整體的事件分發(fā)流程圖,如下:
事件分發(fā)流程圖

以上就是View事件分發(fā)的整體流程圖,相信經(jīng)過上面的總結(jié)之后你會(huì)對(duì)View的事件分發(fā)有更深的認(rèn)識(shí);但是以上只是針對(duì)觸摸事件的Down(單擊)事件來分析的,但是實(shí)際情況中,我們還要對(duì)觸摸事件的Move和Up事件進(jìn)行處理,所以在下一篇文章我們將深入分析在Move和Up的情況下事件的分發(fā)機(jī)制;

最后編輯于
?著作權(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ù)。

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