Android事件分發(fā)筆記

我們主要研究的幾個(gè)方法:dispatchTouchEvent,onInterceptTouchEvent,onTouch, onTouchEvent,onClick。

  • dispatchTouchEvent
    該方法主要是用來進(jìn)行事件分發(fā)和傳遞的,當(dāng)返回true的時(shí)候代表自己去處理,把事件傳遞給自己,否則就傳遞給其他的view。該方法也是觸摸事件第一個(gè)執(zhí)行的方法,后續(xù)的幾個(gè)是否執(zhí)行都取決于它。
  • onInterceptTouchEvent
    這個(gè)方法主要是viewGroup特有的,用來做觸摸事件攔截的,默認(rèn)返回false。
    • 主要是用來做事件分發(fā)過程中的攔截的,相當(dāng)于一個(gè)攔截器
    • 如果返回false或者super,則事件繼續(xù)傳遞,事件所經(jīng)過的每一層的viewGroup都會(huì)去調(diào)用該方法來詢問是否攔截
    • 如果返回true,則代表攔截該事件,停止傳遞給子view,會(huì)走自己的onTouchEvent事件
    • 不像onTouchEvent是否攔截取決于down事件,該方法每個(gè)事件都可以去做攔截
    • 事件一經(jīng)攔截,后續(xù)move、up事件都直接交給onTouchEvent,不會(huì)重新去詢問是否攔截(即不再調(diào)用onInterceptTouchEvent)
    • 事件被攔截后,子view會(huì)接收到一個(gè)cancel事件,來恢復(fù)之前的狀態(tài),結(jié)束當(dāng)前事件流
  • onTouch
    這個(gè)也是觸摸事件,方便給開發(fā)者調(diào)用的。根據(jù)注釋:當(dāng)一個(gè)觸摸事件被分發(fā)到一個(gè)view的時(shí)候,就會(huì)調(diào)用該方法,它是在事件傳遞到onTouchEvent之前被調(diào)用的。
  • onTouchEvent
    該方法就是真正用來處理觸摸事件的最后調(diào)用的方法,在這里你可以自己寫你的觸摸事件算法。
  • onClick
    這個(gè)就是我們最熟悉的點(diǎn)擊事件了,它也屬于觸摸事件的一個(gè)內(nèi)容,有一點(diǎn)需要注意就是他是在onTouchEvent的UP事件里面執(zhí)行的。
    執(zhí)行順序:onTouch—>onTouchEvent—>onClick
  • 事件流程圖


    事件分發(fā)流程圖.png
  • 說明
    • dispatchTouchEvent和onTouchEvent一旦返回true,事件就被消費(fèi)掉了,該事件就消失了,不會(huì)往下傳遞也不會(huì)向上回溯
    • dispatchTouchEvent和onTouchEvent一旦返回false,事件就會(huì)回溯到父控件的onTouchEvent,說明自己不處理
    • dispatchTouchEvent返回false和true對于Activity來說都是一樣,因?yàn)樗亲铐攲拥氖录邮照?,而ViewGroup和View返回super則是向下傳遞,返回false就是向父控件的onTouchEvent回溯事件。
    • onTouchEvent返回super代表向上回溯事件,返回false則代表自己不處理,所以也是向上回溯事件,如果最終都沒消費(fèi),則Activity消費(fèi),事件消失。
    • onInterceptTouchEvent默認(rèn)返回super,通過源碼我們知道其實(shí)就是返回false,默認(rèn)是不去攔截事件的,這也符合常理,可以讓子view有機(jī)會(huì)去捕獲事件,返回true則代表攔截了這個(gè)事件,交給自己的onTouchEvent去處理,ViewGroup的dispatchTouchEvent的super默認(rèn)實(shí)現(xiàn)就是調(diào)用自己的onInterceptTouchEvent,這也就可以保證事件有機(jī)會(huì)分發(fā)到自己的onTouchEvent
    • dispatchTouchEvent和onTouchEvent都是以Down事件為基準(zhǔn),來判斷后續(xù)事件是否經(jīng)過自己,也就是自己消費(fèi),如果Down事件返回了false或者super,則后續(xù)事件都不再經(jīng)過自己了,包括move,up,如只有返回true的時(shí)候,后續(xù)事件才會(huì)經(jīng)過自己
  • 實(shí)例
    • case 1 : 全部返回super


      圖片.png
    • case 2:view的onTouchEvent 返回true


      圖片.png
    • case 3:View的dispatchTouchEvent返回true


      圖片.png
    • case 4:ViewGroup的onTouchEvent返回true


      圖片.png
    • case 5:ViewGroup的onInterceptTouchEvent返回true,并且onTouchEvent也返回true


      圖片.png

      可以看到被攔截之后,后續(xù)move,up事件都交給自己處理,并且不再調(diào)用onIntercepetTouchEvent,而且事件也不再傳遞到子View。

  • 關(guān)于ACTION_DOWN
    • 首先,對于dispatchTouchEvent和onTouchEvent,事件是否消費(fèi)實(shí)在DOWN中決定的,如果DOWN中沒有返回true,則后續(xù)的move,up都不會(huì)再來。
    • 舉例:view的onTouchEvent中DOWN事件返回true


      圖片.png

      可以看到,相比view的onTouchEvent中返回true,多出了最后一行日志。這是因?yàn)橹挥衐own返回了true,僅僅是讓后續(xù)事件經(jīng)過自己,但是move、up事件返回的還是super,而ViewGroup的onTouchEvent事件已經(jīng)被跳過,所以up事件回溯到Activity了。在move,up事件中返回true則起不到在down中返回true的效果。

    • 再舉一例:我們在view的onTouchEvent中down事件返回false看一下:


      圖片.png

      可以看到,down中返回false之后,后續(xù)move,up事件都不在經(jīng)過自己了,所以說down事件起到了決定事件流向的作用。

    • 為了解釋清楚,我們再把view的dispatchTouchEvent的DOWN返回true看一下:


      圖片.png

      可以看到,事件走到View的dispatchTouchEvent后就停止了,因?yàn)檫@里返回了true,代表事件在這里消費(fèi)了,而后續(xù)的UP事件同樣也是走到view的dispatchTouchEvent,由于up返回的是super,所以走了自身的onTouchEvent的up,然后這里返回的也是super,所以又回溯給Activity的onTouchEvent的up了。

    • 對應(yīng)的view的dispatchTouchEvent的DOWN返回false
      圖片.png

      前面提到過,對于dispatchTouchEvent和onTouchEvent,事件是否消費(fèi)實(shí)在DOWN中決定的,如果DOWN中沒有返回true,則后續(xù)的move,up都不會(huì)再來。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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