簡述
1.View對觸摸事件的處理機制
2.ViewGroup對觸摸事件的處理機制
3.android對觸摸體系的概念
4.混合ViewGroup、View的分發(fā)攔截機制
1.View對觸摸事件的處理機制
View中觸摸事件方法有兩個:dispatchTouchEvent、onTouchEvent
調(diào)用順序為 :dispatchTouchEvent ——> onTouchEvent
public boolean dispatchTouchEvent(MotionEvent event) {
//省略......
? ? if (mInputEventConsistencyVerifier !=null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
? ? }//省略......
if (!result && onTouchEvent(event)) {
result =true;
? ? ? ? }
}
//省略
......
return result;
}
2.ViewGroup對觸摸事件的處理機制
ViewGrouop中觸摸事件方法有三個dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent
調(diào)用順序為 :dispatchTouchEvent ——> onInterceptTouchEvent?——> onTouchEvent
// ViewGrouo源碼分析
@Override
public boolean?dispatchTouchEvent(MotionEvent ev) {if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(ev, 1); }// 省略
..........if (actionMasked == MotionEvent.ACTION_DOWN?||mFirstTouchTarget !=null) {
final boolean disallowIntercept = (mGroupFlags &FLAG_DISALLOW_INTERCEPT) !=0;
if (!disallowIntercept) {? // 如果返回false
intercepted =?onInterceptTouchEvent(ev); // 方法傳遞
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
從源碼可以看出來所有觸摸事件的觸發(fā)都是在?dispatchTouchEvent 方法開始的,如果對源碼感興趣的同學(xué)可以去看一下哦!
3.android對觸摸體系的概念
在android中對觸摸事件有兩個概念:分發(fā)、攔截
注意:在UI中,對觸摸事件的處理是從父類開始執(zhí)行的,首先執(zhí)行了父類的dispatchTouchEvent 才會去執(zhí)行子類的?dispatchTouchEvent,遵循先父后子的原則
分發(fā)
分發(fā)可以理解為傳遞的意思,是觸摸view之后所傳遞執(zhí)行事件方法的一種機制:?
? ? ? ?view: dispatchTouchEvent 方法分發(fā)給 onTouchEvent 方法
? ? ? ?viewGroup :dispatchTouchEvent 方法分發(fā) 給onInterceptTouchEvent方法分發(fā) 給?onTouchEvent 方法
分發(fā)機制就是調(diào)用dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent方法的時候返回值為false
分發(fā)可以事件對本身的分發(fā),也可以是向下View(ViewGroup)分發(fā)
攔截
攔截可以理解為對該事件停止向下View(ViewGroup)或本身傳遞觸摸事件
攔截機制就是對調(diào)用dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent方法的時候返回值為true
攔截事件之后,就不再向下傳遞消息機制了
混合ViewGroup、View的分發(fā)攔截機制
舉個例子說明一下。看圖

圖中有四個View:View A、View B、View C、View D
其中View B和View D是view,View A和View C是ViewGroup
接下來我們對該試圖進行觸摸事件操作:
1、從 View A 視圖開始操作:
我們對 A 試圖進行操作,系統(tǒng)首先會調(diào)用?dispatchTouchEvent 方法,判斷該返回值。如果是 true 則攔截事件,剩下的方法都不會被調(diào)用,如果是 false ,則會調(diào)用?onInterceptTouchEvent 方法判斷返回值。如果是true,則會調(diào)用 A 中的?onTouchEvent 方法,如果是 false 則會判斷被觸摸發(fā)該區(qū)域是否有子view,發(fā)現(xiàn)沒有,則同樣會調(diào)用 A 的?onTouchEvent 方法。

2、從 View B 試圖開始操作
我們對B試圖進行操作,因為 B 的存在父試圖 View A,所以首先android系統(tǒng)會先調(diào)用 A 的?dispatchTouchEvent 方法,在該方法進行判斷返回值。如果返回 true,剩下的方法不會執(zhí)行,返回 false,則會調(diào)用 A 的?onInterceptTouchEvent方法,判斷返回值。如果為true,則調(diào)用 A 的?onTouchEvent 方法,如果為 false,則會調(diào)用 View B 的?dispatchTouchEvent ?方法進行判斷,如果返回true,剩下的方法不會調(diào)用,直接返回 View A中的 ?onTouchEvent 方法,如果返回false,因為View B 是 View ,沒有?onInterceptTouchEvent ?方法,所以直接會調(diào)用?onTouchEvent 方法,判斷返回值。如果返回true,說明該事件已經(jīng)被處理,如果返回false,則會調(diào)用 父View A 的?onTouchEvent ?方法。

3、從 View C 視圖開始操作
首先會調(diào)用 A 的?dispatchTouchEvent 方法,true剩下的方法不會調(diào)用,false調(diào)用 A 的 onInterceptTouchEvent 方法判斷。true調(diào)用 A 的 onTouchEvent ?方法,false 調(diào)用 C 的?dispatchTouchEvent 方法判斷返回值。true返回 A 的?onTouchEvent ?方法,false調(diào)用 C 的?onInterceptTouchEvent ?方法判斷。true返回 A 的?onTouchEvent ?方法,false調(diào)用 C 的 ?onTouchEvent ?方法判斷。true調(diào)用 A 的onTouchEvent ?,false 先判斷該視圖是否有子View,有就分發(fā)機制給子view,沒有就返回 A 的?onTouchEvent ?方法。

4.從 View D 試圖操作
首先執(zhí)行 3 的操作到 View C試圖分發(fā)機制到 View D 的?dispatchTouchEvent 方法,true就處理完事件處理返回 View C 的?onTouchEvent ?方法再返回到 View A 的onTouchEvent ?方法,false 就先返回到 View C ?的onTouchEvent ?方法再返回到 View A 的?onTouchEvent ? 方法。

有興趣的同學(xué)可以試一下哦
我說的不是很清晰,希望大神看到可以指正錯誤