ViewGroup是個(gè)抽象類,具體實(shí)現(xiàn)都是在其自類中實(shí)現(xiàn),此處主要是來分析一下Touch事件的分發(fā)機(jī)制。
Touch事件分發(fā)是一個(gè)自上而下的過程,本質(zhì)上為一次DFS深度遍歷,大致的順序?yàn)橛葾ctivity --> ViewGroup --> View。
最先由Activity捕獲然后進(jìn)行分發(fā);然后判斷當(dāng)前的View是否為ViewGroup,如果是ViewGroup則由ViewGroup再次進(jìn)行分發(fā),遍歷其所有的各個(gè)子View。
ViewGroup分發(fā)前需要調(diào)用onInterceprtTouchEvent函數(shù),該函數(shù)用來捕獲TouchEvent,默認(rèn)返回false,如果返回true,則該TouchEvent已被消費(fèi),結(jié)束分發(fā),可以用來屏蔽子View的TouchEvent等。
ViewGroup本身并不會(huì)響應(yīng)TouchEvent,只是起到一個(gè)遍歷的作用,如果子View不是ViewGroup的時(shí)候,則調(diào)用View的分發(fā)機(jī)制。如果TouchEvent沒有被消費(fèi),則前往兄弟節(jié)點(diǎn)或父節(jié)點(diǎn)。
View的分發(fā)機(jī)制中,優(yōu)先View.onTouchListener.onTouch()函數(shù),其次再響應(yīng)View.onTouchEvent()函數(shù)。
當(dāng)遍歷完所有View,TouchEvent還沒被消費(fèi)完時(shí),最后調(diào)用Activity.onTouchEvent(),無論此處是否有響應(yīng),整個(gè)分發(fā)就到此結(jié)束了。

以下從源碼角度進(jìn)行以下分析
Acitivity
事件最先由DecorView進(jìn)行響應(yīng),然后回調(diào)Activity的dispatchTouchEvent函數(shù),onUserInteraction函數(shù)主要用于協(xié)助操作狀態(tài)欄等,可以先無視,getWindow函數(shù)獲取的是PhoneWindow的對象,通過Window分發(fā)到下層的View。
遍歷完整個(gè)View,TouchEven還沒有被消費(fèi)時(shí),才會(huì)調(diào)用Activity的onTouchEvent函數(shù)。
這個(gè)函數(shù)相當(dāng)于分發(fā)的起點(diǎn)和終點(diǎn)。

PhoneWindow
PhoneWindow是Window的子類,調(diào)用基類的dispatchTouchEvent函數(shù),此處基類即為ViewGroup。

ViewGroup
ViewGroup中的事件分發(fā)比較復(fù)雜,有很多過濾,清空的邏輯,所以我們主要看下關(guān)鍵的幾段代碼。
此處為父View攔截TouchEvent的onInterceptTouchEvent函數(shù),如果要禁止父View的攔截,子View可以在OnTouchEvent中調(diào)用getParent().requestDisallowInterceptTouchEvent(true)函數(shù)來禁止onInterceptTouchEvent函數(shù)的調(diào)用。
