一、View事件分發(fā)
先看看這幾種現(xiàn)象View與Touch事件相關(guān)的兩個方法
1.1 dispatchTouchEvent事件分發(fā)
源碼中俯萌,首先將result = false;
boolean result = false;
再拿到ListenerInfo惧所, 存放了關(guān)于View的所有Listener信息如 OnTouchListener 、OnClickListener等
ListenerInfo li = mListenerInfo;
若onTouchListener.onTouch()返回true埠对,則result置為true术健;
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
再往下看汹碱, 如果 result = false 就會執(zhí)行onTouchEvent; 如果result = true 就不會執(zhí)行onTouchEven荞估,這里就解釋了咳促,會先執(zhí)行onTouchListener中的方法稚新。
if (!result && onTouchEvent(event)) {
result = true;
}
目前還未看到有點擊事件onClick(),進入到onTouchEvent()中,
case MotionEvent.ACTION_UP: 里面調(diào)用了 performClick()
switch (action) {
case MotionEvent.ACTION_UP:
//.....其他代碼省略
if (mPerformClick == null) {
mPerformClick = new PerformClick();
}
if (!post(mPerformClick)) {
performClickInternal();
}
所以當onTouchEvent()返回true時,不會執(zhí)行onClick()跪腹,又或者說只有當調(diào)用了onTouchEvent的super()方法時褂删,才會執(zhí)行onClcik().
因為onClick()方法是在View.onTouchEvent的super()方法中。
二冲茸、ViewGroup事件分發(fā)
**dispatchTouchEvent() **事件分發(fā):
boolean handled = false;
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
在ACTION_DOWN事件中屯阀,先將TouchTargets 清除,
并且將mFirstTouchTarget = null
if (actionMasked == MotionEvent.ACTION_DOWN) {
// 清除TouchTargets 只要知道 mFirstTouchTarget = null
cancelAndClearTouchTargets(ev);
resetTouchState();
}
再到onInterceptTouchEvent()事件轴术,正常情況返回false难衰;
onInterceptTouchEvent()返回false時,反序獲取子View膳音,執(zhí)行子View的dispatchTouchEvent()方法召衔;onInterceptTouchEvent()返回true時,將不執(zhí)行子view的方法祭陷。
//是否攔截
final boolean intercepted;
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
//子類是否請求攔截
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
//正常情況下苍凛,會走到onInterceptTouchEvent()中
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action);
} else {
intercepted = false;
}
} else {
intercepted = true;
}
if (!canceled && !intercepted) {
if (newTouchTarget == null && childrenCount != 0) {
for (int i = childrenCount - 1; i >= 0; i--) {
// 反序的for循環(huán) 獲取子 View child,執(zhí)行子類的dispatchTouchEvent
//這里如果子類沒有一個地方返回true兵志,默認是返回false醇蝴,則不會進入判斷
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
// 如果子 View 返回true 就會進來 主要給 mFirstTouchTarget = target;
// 這種情況,move和up事件進來的時候想罕,不會調(diào)用子view 的dispatchTouchEvent事件悠栓。
// 最后調(diào)用到自己的dispatchTouchEvent事件,也就是ViewGroup的按价。
newTouchTarget = addTouchTarget(child, idBitsToAssign);
break;
三惭适、總結(jié)
最后貼個圖總結(jié)下