1. DOWN 事件的流向
【关键点】
dispatchTouchEvent、onTouchEvent返回true:事件就停止传递了(没有谁能再收到这个事件)。dispatchTouchEvent返回false:事件停止往子 View 传递和分发同时开始往父控件回溯,就像递归停止然后开始回溯。dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent返回super.xxxxxx():事件会依照 U 型路径走完整个事件。
2. MOVE 和 UP 事件的流向
2.1. dispatchTouchEvent 返回 true
则 ACTION_MOVE 和 ACTION_UP 的事件传到这个 View 后就不再往下传递了,并立即消费掉。
2.2. onTouchEvent 返回 true
则 ACTION_MOVE 和 ACTION_UP 的事件传到这个 View 后就不再往下传递了,并传给自己的 onTouchEvent 消费掉。
2.3. 总结
ACTION_DOWN事件在哪个控件消费了(return true), 那么ACTION_MOVE和ACTION_UP就会从上往下(通过dispatchTouchEvent)做事件分发往下传,就只会传到这个控件,不会继续往下传。- 如果
ACTION_DOWN事件是在dispatchTouchEvent消费,那么事件到此为止停止传递。 - 如果
ACTION_DOWN事件是在onTouchEvent消费的,那么会把ACTION_MOVE或ACTION_UP事件传给该控件的onTouchEvent处理并结束传递。
3. setOnTouchListener
public boolean dispatchTouchEvent(MotionEvent event) {
// ...
boolean result = false;
// ...
if (onFilterTouchEventForSecurity(event)) {
// ...
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
// 优先处理OnTouchListener
// 如果返回值是true,则不会再执行自身的onTouchEvent,并消费该事件
result = true;
}
// 转交给自己的onTouchEvent
if (!result && onTouchEvent(event)) {
result = true;
}
}
// ...
return result;
}
【结论】
- 未设置
OnTouchListener,系统默认执行onTouchEvent(event)方法。 - 设置了
OnTouchListener,系统会先执行它,并根据其返回值再决定是否执行onTouchEvent(event)。 - 看
OnTouchListener的优先级比onTouchEvent高。