淺談Android事件分發(fā)

@[toc]

何為事件分發(fā)

  • 基礎(chǔ)知識(shí)

事件:MotionEvent(點(diǎn)擊事件)

事件列:從手指接觸屏幕至手指離開(kāi)屏幕的這個(gè)過(guò)程所產(chǎn)生的一系列事件,一般情況下,點(diǎn)擊事件都是從DOWN事件開(kāi)始,UP事件結(jié)束,中間經(jīng)歷若干個(gè)MOVE事件。

事件類(lèi)型:
手指按下 -->產(chǎn)生DOWN事件
手指滑動(dòng) -->產(chǎn)生MOVE事件
手指抬起 -->產(chǎn)生UP事件

  • 定義理解:一般來(lái)說(shuō),事件分發(fā)就是將點(diǎn)擊事件分發(fā)(可以理解為傳遞)到一個(gè)view去處理該事件。

ACTION_DOWN事件怎么傳遞和處理的

看了不少文章,po一張比較好理解的圖:基于ACTION_DOWN事件走向。
來(lái)源Kelin

先對(duì)這圖做一些基本說(shuō)明:

  • true---該控件或activity消費(fèi)事件,事件不再被傳遞。
  • false---該控件或actiivty不消費(fèi)事件,事件被繼續(xù)傳遞。
  • super---調(diào)用該方法的父類(lèi)實(shí)現(xiàn),在方法中可修改返回值。
  • dispatchTouchEvent()---事件首先到達(dá)的方法。用于分發(fā)點(diǎn)擊事件,一般不會(huì)重寫(xiě)這個(gè)方法。
  • onInterceptTouchEvent()---判斷是否攔截該事件,用來(lái)攔截事件。
  • onTouchEvent()---判斷是否消費(fèi)該事件,用來(lái)處理事件。
在這里插入圖片描述

上圖很明顯地表示了系統(tǒng)默認(rèn)的對(duì)于down事件的傳遞方式。我們可以觀察到這些事件在三個(gè)對(duì)象間進(jìn)行傳遞,分別是activity,viewgroup,view。
總結(jié):
activity層的dispatchTouchEvent()---調(diào)用--->activity層父類(lèi)的dispatchTouchEvent()(默認(rèn)實(shí)現(xiàn)是調(diào)用viewgroup層的dispatchTouchEvent())---調(diào)用--->super的默認(rèn)實(shí)現(xiàn) viewgroup層onInterceptTouchEvent()---調(diào)用--->【默認(rèn)返回false】super的默認(rèn)實(shí)現(xiàn)view層dispatchTouchEvent()---調(diào)用--->super的默認(rèn)實(shí)現(xiàn)view層的onTouchEvent()

在這之后,如圖,默認(rèn)情況下,view層和Viewgroup都不進(jìn)行消費(fèi),那么就會(huì)一路傳給了activity層的onTouchEvent()進(jìn)行消費(fèi)。
于是出現(xiàn)了類(lèi)似U型的流程走向。

po另外一張圖,來(lái)源還是 Kelin

在這里插入圖片描述

注:右上角的橫線表明返回值
我們可以很清楚地看到整個(gè)的流程,有幾點(diǎn)總結(jié)一下

1.只有viewgroup才有 onInterceptTouchEvent()方法。

2.當(dāng)viewgroup層的 onInterceptTouchEvent()返回值為true,表明該viewgroup想要處理這個(gè)事件,那么這個(gè)事件便會(huì)傳遞給其onTouchEvent()進(jìn)行處理。

3.如果onTouchEvent()或者dispatchTouchEvent()不想處理事件,返回false,則拋給上級(jí)的onTouchEvent()進(jìn)行處理。

4.另外,調(diào)用優(yōu)先級(jí):
onTouchListener的onTouch>View的onTouch>onClickListener
當(dāng)一個(gè)view需要處理事件時(shí),如果它設(shè)置了onTouchListener,那么onTouchEvent()中的onTouch()會(huì)被回調(diào)。如果該方法返回值為true,那么當(dāng)前view的onTouchEvent()將不會(huì)被調(diào)用,返回false才會(huì)調(diào)用到view的onTouchEvent()。這個(gè)時(shí)候再onTouchEvent()中設(shè)置的onClickListener()才會(huì)被調(diào)用。

ACTION_MOVE和ACTION_UP事件怎么傳遞和處理的

詳細(xì)可參考博客中的參考圖片及相關(guān)說(shuō)明。此處不再贅述,只做總結(jié)。

  • 總結(jié)
    • 1.當(dāng)一個(gè)view決定攔截一個(gè)事件后,系統(tǒng)會(huì)把同一個(gè)事件系列內(nèi)的所有事件都交給他處理,此時(shí)不需要再調(diào)用攔截器詢(xún)問(wèn)是否需要攔截。因此同一個(gè)事件系列中的事件一般也只由一個(gè)view進(jìn)行處理。
    • 2.在DOWN事件發(fā)生時(shí),如果某個(gè)view的onTouchEvent()被調(diào)用,但是返回了false[即不想處理],那么該事件系列后續(xù)的事件也不再傳遞給他,乃是傳給其父類(lèi)viewgroup的onTouchEvent()。這一點(diǎn)的話(huà)很像是上級(jí)交給程序員一個(gè)任務(wù),他沒(méi)完成,交給他的上級(jí)完成。那么短時(shí)間內(nèi)他的上級(jí)就不會(huì)交給他相關(guān)任務(wù)了。
      這個(gè)時(shí)候我們可能會(huì)發(fā)現(xiàn),其實(shí)事件分發(fā)的機(jī)制可以用領(lǐng)導(dǎo)交給下級(jí)任務(wù)這種職場(chǎng)常見(jiàn)模式進(jìn)行分析,或許這樣會(huì)更加容易理解。
    • 3.在哪個(gè)對(duì)象的onTouchEvent()進(jìn)行消費(fèi),那么后續(xù)的事件都會(huì)給其進(jìn)行處理。

事件分發(fā)是第一次接觸的東西,源碼和實(shí)例等等還沒(méi)有進(jìn)行研究。若有錯(cuò)誤之處,還望各位不吝賜教。

作者介紹

-楊曉華:廣州蘆葦科技 APP 團(tuán)隊(duì) Android 開(kāi)發(fā)

內(nèi)推信息

?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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