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

點(diǎn)擊事件用MotionEvent來(lái)表示,當(dāng)一個(gè)點(diǎn)擊操作發(fā)生時(shí),事件最先傳遞給當(dāng)前Activity,由Activity的dispatchTouchEvent來(lái)進(jìn)行事件的分發(fā),具體工作是由Activity內(nèi)部的Window(也就是PhoneWindow)來(lái)完成的,window會(huì)講事件傳遞給decorView,decorView是當(dāng)前界面的底層容器(即 setContectView所設(shè)置的view的父容器),decorView調(diào)用ViewGroup的dispatchTouchEvent將事件分發(fā)到view(也就是setContectView所設(shè)置的view),當(dāng)事件達(dá)到頂級(jí)View(一般是viewgroup)后會(huì)調(diào)用ViewGroup的dispatchTouchEvent,如果頂級(jí)ViewGroup攔截事件,即onInterceptTouchEvent方法返回true,則事件由ViewGroup處理,這時(shí)如果ViewGroup的mOnTouchListener被設(shè)置,則onTouch方法會(huì)被調(diào)用,否則onTouchEvent被調(diào)用,也就是說(shuō)如果都提供onTouch會(huì)屏蔽掉onTouchEvent。如果頂級(jí)view不攔截事件,則會(huì)傳遞給他的子View,這時(shí)子View的dispatchTouchEvent方法會(huì)被調(diào)用,如果子View是ViewGroup,則事件傳遞過(guò)程跟頂級(jí)View一樣,否則如果子View設(shè)置OnTouchListener被設(shè)置,則onTouch方法會(huì)被調(diào)用,否則onTouchEvent被調(diào)用,若都沒(méi)有消費(fèi)此事件最終將會(huì)傳遞給Activity處理。

注意

  • 同一事件序列是指從手指接觸屏幕起,到手指離開(kāi)屏幕這一過(guò)程中所產(chǎn)生的一系列事件,事件中有dowm,許多move和up

  • 正常情況下,一個(gè)事件序列只能被一個(gè)View攔截且消耗

  • 一旦某一元素?cái)r截了事件,那么同一事件序列的所有事件都會(huì)直接交給他處理,并且它的onInterceptTouchEvent方法將不會(huì)再被調(diào)用,但是可通過(guò)強(qiáng)制手段將同一事件序列的事件分別由不同的view來(lái)同時(shí)處理,比如:一個(gè)view將本該自己處理的事件通過(guò)onTouchEvent強(qiáng)行傳遞給其他View

  • 事件傳遞總是由外向內(nèi)的,子View可以通過(guò)requestDisallowInterceptTouchEvent來(lái)干擾父View的事件分發(fā)過(guò)程,但是ACTION_DOWN除外

  • activity:


    image.png
  • PhoneWindow:


    image.png
  • DecorView:


    image.png
  • ViewGroup:


    image.png
最后編輯于
?著作權(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)容