在Android開(kāi)發(fā)中脚仔,事件分發(fā)機(jī)制是Android比較重要的知識(shí)悔醋,熟練應(yīng)用分發(fā)機(jī)制有助于更好的解決滑動(dòng)沖突點(diǎn)擊失效等問(wèn)題救崔,更容易的去開(kāi)發(fā)自定義控件扶供。當(dāng)然Android面試時(shí)事件分發(fā)機(jī)制是一個(gè)躲不掉的問(wèn)題筛圆,能搞清事件分發(fā)的來(lái)龍去脈,好工作就不遠(yuǎn)了椿浓。
Android事件分發(fā)機(jī)制的發(fā)生在View與View之間或者ViewGroup與View之間太援,當(dāng)一個(gè)點(diǎn)擊事件產(chǎn)生后,它的傳遞過(guò)程遵循如下順序:Activity->Window(PhoneWindow)->View ??
(如圖1)
Android事件分發(fā)機(jī)制主要由三個(gè)重要的方法共同完成的
dispatchTouchEvent:用于進(jìn)行點(diǎn)擊事件的分發(fā)
onInterceptTouchEvent:用于進(jìn)行點(diǎn)擊事件的攔截
onTouchEvent:用于處理點(diǎn)擊事件
只有在ViewGroup中才有onInterceptTouchEvent()方法的
下面我們通過(guò)例子介紹一下 用重寫(xiě)了三個(gè)重要方法的兩個(gè)ViewGroup 和重寫(xiě)了兩個(gè)方法的View
兩個(gè)ViewGroup是同樣的 (如圖2)
下面是重寫(xiě)的View(如圖3)
我們的界面效果圖(如圖4)
在我們不做任何處理的情況下點(diǎn)擊我們的View1 也就是紅色區(qū)域? 我們的log輸出為(如圖5)
從我們的日志中可以看出我們事件的分發(fā)有兩個(gè)過(guò)程 分發(fā)過(guò)程和處理過(guò)dispatchTouchEvent和onInterceptTouchEvent是分發(fā)過(guò)程onTouchEvent是處理過(guò)程扳碍。事件分發(fā)是由我們的父控件向子控件進(jìn)行分發(fā)提岔,子控件向控件反饋處理。
下面我們進(jìn)行對(duì)dispatchTouchEvent方法進(jìn)行處理 分發(fā)事件?
我們把ViewGroup2的dispatchTouchEvent返回值變?yōu)閠rue 表示該控件消費(fèi)掉該事件不再分發(fā)也不會(huì)再處理該事件(如圖6)
我們把ViewGroup2的dispatchTouchEvent返回值變?yōu)閒alse 表示在該控件這里不再分發(fā)繼續(xù)分發(fā)并把事件交由父控件處理(如圖7)
下面我們進(jìn)行對(duì)onInterceptTouchEvent方法進(jìn)行處理 事件的攔截
我們把ViewGroup2的onInterceptTouchEvent返回值變?yōu)閒alse 表示該控件不會(huì)攔截該事件 繼續(xù)分發(fā) log輸出信息(如圖5)與我們不做處理時(shí)是一樣的?
我們把ViewGroup2的onInterceptTouchEvent返回值變?yōu)閠rue 表示該控件攔截該事件 不再往子空間進(jìn)行分發(fā)笋敞,然后進(jìn)行層級(jí)的處理過(guò)程 ?(如圖8)
下面我們進(jìn)行對(duì)onTouchEvent方法進(jìn)行處理 事件的處理
我們把View1的onTouchEvent返回值變?yōu)閠rue 表示該控件處理該事件碱蒙,不再往父控件反饋 ?(如圖9)
簡(jiǎn)單總結(jié) ? 事件分發(fā)的過(guò)程是由父控件向子控件進(jìn)行分發(fā) ?子控件可以選擇處理該事件也可以繼續(xù)分發(fā)也可以反饋給上級(jí)處理。就是這樣的一個(gè)層級(jí)過(guò)程。