android事件传递顺序:Activity -> ViewGroup -> View。
各自事件:
-
Activity
- dispatchTouchEvent
- onTouchEvent
-
ViewGroup
- dispatchTouchEvent
- onInterceptTouchEvent
- onTouchEvent
-
View
- dispatchTouchEvent
- onTouchEvent
demo
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.lexchat.view.ViewGroupA
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fa0"
android:orientation="vertical"
android:padding="20dp">
<com.example.lexchat.view.ViewA
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#ff0000"
android:text="ViewA"/>
<com.example.lexchat.view.ViewGroupB
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#00ff00"
android:layout_marginTop="10dp"
android:gravity="center">
<com.example.lexchat.view.ViewB
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#0000ff" />
</com.example.lexchat.view.ViewGroupB>
</com.example.lexchat.view.ViewGroupA>
</LinearLayout>

默认流程
点击ViewA事件:
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewA dispatchTouchEvent -----> ACTION_DOWN
ViewA onTouchEvent -----> ACTION_DOWN
ViewGroupA onTouchEvent -----> ACTION_DOWN
TouchActivity onTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
TouchActivity onTouchEvent -----> ACTION_UP
点击ViewGroupA事件:
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupA onTouchEvent -----> ACTION_DOWN
TouchActivity onTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
TouchActivity onTouchEvent -----> ACTION_UP
通过ViewA和ViewGroupA的事件可以看到事件如果在传递过程中没有被消费的话(return true),是从Activity的dispatchTouchEvent开始的,然后按层级依次向下传递,直到最后一个View或者ViewGroup,调用它的onTouchEvent;然后依次向上传递,直到Activity的onTouchEvent。看着是一个U型结构:

事件消费
dispatchTouchEvent
Activity
测试代码:
public boolean dispatchTouchEvent(MotionEvent ev) {
MotionEventUtil.log(TAG, "dispatchTouchEvent", ev.getAction());
boolean result = super.dispatchTouchEvent(ev);
MotionEventUtil.log(TAG, "super.dispatchTouchEvent", ev.getAction(), result);
return result;
}
boolean result = true 执行结果:
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
boolean result = false 结果:
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
观察上面dispatchTouchEvent不管返回true或者false,本次事件(ACTION_DOWN)立即结束,不再向下传递。
ViewGroup
ViewGroupA的dispatchTouchEvent 返回true,点击ViewA:
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
ViewGroupA dispatchTouchEvent -----> ACTION_UP
ViewGroupA执行完dispatchTouchEvent事件直接结束。
ViewGroupB的dispatchTouchEvent 返回true,点击ViewB
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupB dispatchTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
ViewGroupA dispatchTouchEvent -----> ACTION_UP
ViewGroupA onInterceptTouchEvent -----> ACTION_UP
ViewGroupB dispatchTouchEvent -----> ACTION_UP
ViewGroupB执行完dispatchTouchEvent直接结束。
View
ViewB的dispatchTouchEvent 返回true,点击ViewB
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupB dispatchTouchEvent -----> ACTION_DOWN
ViewGroupB onInterceptTouchEvent -----> ACTION_DOWN
ViewB dispatchTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
ViewGroupA dispatchTouchEvent -----> ACTION_UP
ViewGroupA onInterceptTouchEvent -----> ACTION_UP
ViewGroupB dispatchTouchEvent -----> ACTION_UP
ViewGroupB onInterceptTouchEvent -----> ACTION_UP
ViewB dispatchTouchEvent -----> ACTION_UP
执行到ViewB的dispatchTouchEvent就结束了。
综上当dispatchTouchEvent返回true的时候(返回true就表明本次事件已经消耗掉),不会向下传递也不会向上传递,本次事件就直接结束。
ViewGroupB的dispatchTouchEvent 返回false,点击ViewB
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupB dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onTouchEvent -----> ACTION_DOWN
TouchActivity onTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
TouchActivity onTouchEvent -----> ACTION_UP
ViewB的dispatchTouchEvent 返回false,点击ViewB:
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupB dispatchTouchEvent -----> ACTION_DOWN
ViewGroupB onInterceptTouchEvent -----> ACTION_DOWN
ViewB dispatchTouchEvent -----> ACTION_DOWN
ViewGroupB onTouchEvent -----> ACTION_DOWN
ViewGroupA onTouchEvent -----> ACTION_DOWN
TouchActivity onTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
TouchActivity onTouchEvent -----> ACTION_UP
不管是ViewGroup还是View,如果dispatchTouchEvent返回false,就表明不再向下分发事件,直接交由上一级View的onTouchEvent继续向上传递。
总结:
- 返回super.dispatchTouchEvent
事件继续按U型结构执行,直到被消耗。 - 返回true
表明事件直接就被消耗了,事件不会向下分发也不会向上传递,本次事件就直接结束。 - 返回false
表明不再向下分发事件,直接交由上一级View的onTouchEvent继续向上传递。要注意下次事件的传递.
onInterceptTouchEvent
ViewGroupB的onInterceptTouchEvent 返回true,点击ViewB
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupB dispatchTouchEvent -----> ACTION_DOWN
ViewGroupB onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupB onTouchEvent -----> ACTION_DOWN
ViewGroupA onTouchEvent -----> ACTION_DOWN
TouchActivity onTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
TouchActivity onTouchEvent -----> ACTION_UP
ViewGroupB的onInterceptTouchEvent 返回false,点击ViewB
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupB dispatchTouchEvent -----> ACTION_DOWN
ViewGroupB onInterceptTouchEvent -----> ACTION_DOWN
ViewB dispatchTouchEvent -----> ACTION_DOWN
ViewB onTouchEvent -----> ACTION_DOWN
ViewGroupB onTouchEvent -----> ACTION_DOWN
ViewGroupA onTouchEvent -----> ACTION_DOWN
TouchActivity onTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
TouchActivity onTouchEvent -----> ACTION_UP
和super.onInterceptTouchEvent一样。
总结:
- 返回true 进行事件拦截,停止向下分发,交给自己的onTouchEvent,然后向上传递。
- 返回false和super.onInterceptTouchEvent 不进行拦截,事件向下传递给下级dispatchTouchEvent,按U型结构继续分发。
onTouchEvent
ViewGroupB的onTouchEvent 返回true,点击ViewB
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupB dispatchTouchEvent -----> ACTION_DOWN
ViewGroupB onInterceptTouchEvent -----> ACTION_DOWN
ViewB dispatchTouchEvent -----> ACTION_DOWN
ViewB onTouchEvent -----> ACTION_DOWN
ViewGroupB onTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
ViewGroupA dispatchTouchEvent -----> ACTION_UP
ViewGroupA onInterceptTouchEvent -----> ACTION_UP
ViewGroupB dispatchTouchEvent -----> ACTION_UP
ViewGroupB onTouchEvent -----> ACTION_UP
ViewGroupB的onTouchEvent返回true,事件被消费,事件终止。
ViewB的onTouchEvent返回true,点击ViewB
TouchActivity dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA dispatchTouchEvent -----> ACTION_DOWN
ViewGroupA onInterceptTouchEvent -----> ACTION_DOWN
ViewGroupB dispatchTouchEvent -----> ACTION_DOWN
ViewGroupB onInterceptTouchEvent -----> ACTION_DOWN
ViewB dispatchTouchEvent -----> ACTION_DOWN
ViewB onTouchEvent -----> ACTION_DOWN
TouchActivity dispatchTouchEvent -----> ACTION_UP
ViewGroupA dispatchTouchEvent -----> ACTION_UP
ViewGroupA onInterceptTouchEvent -----> ACTION_UP
ViewGroupB dispatchTouchEvent -----> ACTION_UP
ViewGroupB onInterceptTouchEvent -----> ACTION_UP
ViewB dispatchTouchEvent -----> ACTION_UP
ViewB onTouchEvent -----> ACTION_UP
ViewB消耗事件,事件结束。
总结:
- 返回true 事件被消费,直接结束
- 返回false或者super.onTouchEvent 事件不处理,继续向上传递。
- 下次事件不会走当前消费事件ViewGroup的onInterceptTouchEvent方法。
dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent三个方法如果调用super.XXX,默认都返回false。但是当给View或者ViewGroup支持点击或者长按的话,事件就会被该View或者ViewGroup消费,返回true。比如设置clicklistener或者设置setClickable(true)