本篇文章給大家分享的是有關(guān)Android中怎么實(shí)現(xiàn)事件分發(fā)機(jī)制,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。
站在用戶的角度思考問(wèn)題,與客戶深入溝通,找到當(dāng)雄網(wǎng)站設(shè)計(jì)與當(dāng)雄網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國(guó)際域名空間、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋當(dāng)雄地區(qū)。
一、簡(jiǎn)介
或許你會(huì)問(wèn),“為什么我一定要知道View的事件分發(fā)機(jī)制?”。因?yàn)槲覀冊(cè)趯?shí)際開(kāi)發(fā)的過(guò)程中,經(jīng)常會(huì)遇到多層的View互相嵌套以后,對(duì)某一個(gè)View進(jìn)行滑動(dòng)的時(shí)候,特別不靈敏,甚至于沒(méi)法滑動(dòng)。這種滑動(dòng)沖突的解決需要我們清楚的掌握View的事件分發(fā)機(jī)制。那下面我們?cè)敿?xì)的講解下View的整個(gè)事件機(jī)制。
Android將View的事件封裝到MotionEvent這個(gè)類中,這也是監(jiān)聽(tīng)touch事件中回調(diào)給我們的參數(shù)public boolean onTouchEvent(MotionEvent event)。通常事件我們主要關(guān)心下面幾種類型:
MotionEvent.ACTION_DOWN
當(dāng)我們手指按下屏幕的第一個(gè)事件便是ACTION_DOWN了,也就是意味著事件的開(kāi)始。
MotionEvent.ACTION_MOVE
當(dāng)我們手指按下屏幕后,在屏幕上滑動(dòng)的過(guò)程,此事件就會(huì)不斷的觸發(fā)。
MotionEvent.ACTION_UP
此事件在我們手指從屏幕抬起的時(shí)候會(huì)觸發(fā)。
MotionEvent.ACTION_CANCEL
這個(gè)事件說(shuō)起來(lái)稍微復(fù)雜一點(diǎn),舉個(gè)栗子:當(dāng)我們的外層View將事件傳遞給內(nèi)層View去處理時(shí),外層View的攔截方法一般會(huì)返回false,但是當(dāng)某個(gè)條件觸發(fā)后,外層View想自己處理接下來(lái)的事件,就攔截了事件分發(fā),此時(shí)內(nèi)層View就會(huì)收到ACTION_CANCEL的事件。
MotionEvent.ACTION_OUTSIDE
這個(gè)事件我們不常用到,考慮這種場(chǎng)景。我們又一個(gè)Diallog彈出,當(dāng)我們按Dialog以外的屏幕將Dialog消失掉。這個(gè)時(shí)候可以考慮監(jiān)聽(tīng)這個(gè)事件,要想使用這個(gè)事件我們必須對(duì)當(dāng)前的Window設(shè)置一個(gè)Flag:FLAG_WATCH_OUTSIDE_TOUCH。
下面我們介紹和事件分發(fā)相關(guān)的幾個(gè)方法:
dispatchTouchEvent(MotionEvent event)
這個(gè)方法是用來(lái)處理向下分發(fā)事件邏輯的,我們通過(guò)觀察ViewGrope源碼中的代碼知道,這個(gè)方法細(xì)節(jié)較多,檢出我們比較關(guān)心的邏輯就是這個(gè)方法會(huì)先判斷子View是否有調(diào)用disallowIntercept父View去攔截事件,如果沒(méi)有,父View自己會(huì)調(diào)用onInterceptTouchEvent判斷自己是否有攔截,如果攔截事件,將調(diào)用父View自己的onTouchEvent方法去處理事件,如果沒(méi)有攔截事件,事件將繼續(xù)分發(fā)到子View中處理。
onInterceptTouchEvent(MotionEvent event)
用來(lái)申明是否攔截事件繼續(xù)向下分發(fā),如果返回true,事件將不會(huì)繼續(xù)向下分發(fā),而是交由自己的onTouchEvent方法處理。
onTouchEvent(MotionEvent event)
顯然,這個(gè)就是事件處理的方法了。
onTouch(MotionEvent event)
這個(gè)方法是在我們對(duì)某一個(gè)setOnTouchListener時(shí)回調(diào),也就是在傳遞事件的時(shí)候,在交給View本身的onTouchEvent處理之前判斷是否有監(jiān)聽(tīng)的TouchListener,如果有優(yōu)先調(diào)用TouchListener的onTouch方法處理。
我們都知道,Android的View是樹(shù)形結(jié)構(gòu)的,所以當(dāng)一個(gè)事件來(lái)臨的時(shí)候一般是從根部分發(fā)下來(lái)的。為了方便我們接下來(lái)的理解,我們構(gòu)建一個(gè)這樣的例子:
假設(shè)我們有這樣一個(gè)頁(yè)面,最外層是一個(gè)ViewGroup A,里面嵌套著一個(gè)ViewGroup B,B里面有一個(gè)ViewGroup C。
假設(shè)我們對(duì)事件不做任何攔截,也不做任何處理。當(dāng)我們點(diǎn)擊View C,這個(gè)時(shí)候我們看到的Log顯示調(diào)用順序?yàn)椋?/p>
A -> dispatchTouchEvent
A -> onInterceptTouchEvent
B -> dispatchTouchEvent
B -> onInterceptTouchEvent
C -> dispatchTouchEvent
C -> onInterceptTouchEvent
C -> onTouchEvent ACTION_DOWN
B -> onTouchEvent ACTION_DOWN
A -> onTouchEvent ACTION_DOWN
由于沒(méi)有任何View處理事件,最終會(huì)回調(diào)到Activity的onTouchEvent中去處理。從這個(gè)情景中我們可以知道,事件向下傳遞的過(guò)程以及處理事件的向上傳遞的過(guò)程。
假設(shè)我們?cè)赩iew B的onTouchEvent中返回true,再次點(diǎn)擊事件并滑動(dòng),我們得到的Log如下:
A -> dispatchTouchEvent
A -> onInterceptTouchEvent
B -> dispatchTouchEvent
B -> onInterceptTouchEvent
C -> dispatchTouchEvent
C -> onInterceptTouchEvent
C -> onTouchEvent ACTION_DOWN
B -> onTouchEvent ACTION_DOWN
A -> dispatchTouchEvent
A -> onInterceptTouchEvent
B -> dispatchTouchEvent
B -> onTouchEvent ACTION_MOVE
A -> dispatchTouchEvent
A -> onInterceptTouchEvent
B -> dispatchTouchEvent
B -> onTouchEvent ACTION_UP
我們發(fā)現(xiàn),除了ACTION_DOWN事件會(huì)下發(fā)到C,后續(xù)的事件不會(huì)再下發(fā)這是因?yàn)?,?dāng)我們發(fā)現(xiàn)某一層View的onTouchEvent返回true以后,會(huì)有一個(gè)標(biāo)志位表示后續(xù)的事件都由此View處理,后續(xù)事件不再下發(fā)到子View,直到ACTION UP事件后將標(biāo)志位重置。
假設(shè)我們?cè)赩iew B的onInterceptTouchEvent中返回true,再次點(diǎn)擊C會(huì)怎么樣呢?我們得到如下的Log記錄:
A -> dispatchTouchEvent
A -> onInterceptTouchEvent
B -> dispatchTouchEvent
B -> onInterceptTouchEvent
B -> onTouchEvent ACTION_DOWN
A -> onTouchEvent ACTION_DOWN
相比較于情景2,ACTION_DOWN事件不會(huì)下發(fā)到C,由于沒(méi)有View表示能處理,所以后續(xù)的事件均被取消。
通過(guò)我們實(shí)際運(yùn)行和分析源碼發(fā)現(xiàn),我們ViewGroup事件的分發(fā)流程如下所示:
以上就是Android中怎么實(shí)現(xiàn)事件分發(fā)機(jī)制,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。