所謂點(diǎn)擊事件的事件分發(fā),其實(shí)就是對MotionEvent事件的分發(fā)過程,即當(dāng)一個(gè)MotionEvent產(chǎn)生了以后洋腮,系統(tǒng)需要把這個(gè)事件傳遞給一個(gè)具體的View的這個(gè)過程。點(diǎn)擊事件的分發(fā)過程由三個(gè)很重要的方法共同完成:
-
public boolean dispatchTouchEvent( MotionEvent ev )
如果事件能夠傳遞到當(dāng)前View镀脂,則此方法一定會被調(diào)用。返回結(jié)果受當(dāng)前View的onTouchEvent和下級View的dispatchTouchEvent方法影響忘伞,表示是否消耗當(dāng)前事件狗热。 -
public boolean onInterceptTouchEvent( MotionEvent ev )
ViewGroup特有的方法钞馁,在dispatchTouchEvent方法中調(diào)用虑省,用來判斷是否攔截某個(gè)事件匿刮,默認(rèn)為false,如需攔截則需要重寫該方法探颈。 -
public boolean onTouchEvent( MotionEvent ev )
在dispatchTouchEvent方法中調(diào)用熟丸,用來處理點(diǎn)擊事件,返回結(jié)果表示是否消耗當(dāng)前事件伪节。
用偽代碼來表示三者的關(guān)系:
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean consume = false;
if (onInterceptTouchEvent(ev)) {
consume = onTouchEvent(ev);
} else {
consume = child.dispatchTouchEvent(ev);
}
return consume;
}
簡單描述一下點(diǎn)擊事件的傳遞過程:
當(dāng)一個(gè)點(diǎn)擊事件產(chǎn)生后光羞,它的的傳遞過程遵循如下吮吸:Activity->Window->頂級View,頂級View一般都是一個(gè)ViewGroup怀大,接收到事件后纱兑,就按照事件分發(fā)機(jī)制去分發(fā)事件。
當(dāng)ViewGroup接收到事件后化借,它的dispatchTouchEvent就會被調(diào)用潜慎,如果這個(gè)ViewGroup的onInterceptTouchEvent方法返回true,則表示它要攔截當(dāng)前事件蓖康,接著事件就會交給這個(gè)ViewGroup處理铐炫,即它的onTouchEvent方法就會被調(diào)用,事件不再往下分發(fā)蒜焊。如果這個(gè)ViewGroup的onInterceptTouchEvent方法返回false倒信,就表示它不攔截當(dāng)前事件,事件就會被傳遞到它的子元素去處理泳梆,如此反復(fù)直到事件被最終處理鳖悠。具體流程如下:
值得注意的是:
- View的onTouchEvent默認(rèn)都會消耗事件(返回true),除非它是不可點(diǎn)擊的(clickable和longClickable同時(shí)為false)优妙。View的longClickable屬性默認(rèn)都為false乘综,clickable屬性要分情況,比如Button的clickable默認(rèn)為true鳞溉,TextView的clickable默認(rèn)為false瘾带。
- View的enable屬性不影響onTouchEvent的默認(rèn)返回值,哪怕一個(gè)View是disable狀態(tài)的熟菲,只要它的clickable或者longClickable有一個(gè)為true看政,即該View是可點(diǎn)擊的,它的onTouchEvent都返回true抄罕。
- 在一個(gè)點(diǎn)擊鏈里面允蚣,只要ViewGroup不攔截事件,則必然是子View先響應(yīng)呆贿,子View不消耗該事件時(shí)嚷兔,ViewGroup才響應(yīng)森渐。
- 在同一個(gè)ViewGroup里面,多個(gè)View若是重疊冒晰,且點(diǎn)擊的位置在重疊區(qū)域同衣,則必最外的View必先響應(yīng),該View不消耗該事件時(shí)壶运,下層的View才響應(yīng)耐齐。
結(jié)合郭霖大神的源碼解析,可以更清晰地理解View的分發(fā)響應(yīng)機(jī)制:
Android事件分發(fā)機(jī)制完全解析蒋情,帶你從源碼的角度徹底理解(上)
Android事件分發(fā)機(jī)制完全解析埠况,帶你從源碼的角度徹底理解(下)