---
事件分发机制
---

#### 目录

1. 概述
2. 核心方法
3. 关于 ACTION_MOVE 和 ACTION_UP
4. 参考

#### 概述

事件分发中的事件即指 MotionEvent，传递方向是 Activity -> ViewGroup -> View，然后在回溯。事件分发包含三个核心方法：dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent。

#### 核心方法

##### dispatchTouchEvent

用于事件分发，返回结果表示是否消耗了当前事件。它和 onInterceptTouchEvent 和 onTouchEvent 的关系可以表示为：

```java
public boolean dispatchTouchEvent(MotionEvent ev){
    boolean consume = false;
    if(onInterceptTouchEvent(ev)){
        consume = onTouchEvent(ev);
    }else{
        consume = child.dispatchTouchEvent(ev);
    }
    return consume;
}
```

##### onInterceptTouchEvent

只存在于 ViewGroup 中，只有 ViewGroup 才会决定是否需要拦截事件自己处理。默认是不会拦截的，交给子 View 处理。

##### onTouchEvent

用于事件处理，我们平时设置的 onTouchEventListener 和 onClickListener 都是在其内。

##### 总结

1. 对于 dispatchTouchEvent 和 onTouchEvent ，return true 代表终止时间传递，return false 则是回溯到父 View 的 onTouchEvent 方法。
2. ViewGroup 想把事件分发给自己的 onTouchEvent，需要 onInterceptTouchEvent return true 把事件拦截下来，默认是不拦截的，所以 return super.onInterceptTouchEvent == return false 到 View.dispatchTouchEvent。
3. View 没有拦截器，为了让 View 可以把事件分发给自己的 onTouchEvent，View 的 dispatchTouchEvent 默认实现（super）就是把事件分发给自己的 onTouchEvent。

#### 关于 ACTION_MOVE 和 ACTION_UP

上面都是针对 ACTION_DOWN 的时间传递，ACTION_MOVE 和 ACTION_UP 在传递的过程中并不是和 ACTION_DOWN 一样。如果在执行 ACTION_DOWN 的时候返回了 false，后面一系列其他的 action 就不会再得到执行了。简单来说，就是当 dispatchTouchEvent 在进行事件分发的时候，只有前一个事件（如 ACTION_DOWN）返回 true，才会收到 ACTION_MOVE 和 ACTION_UP 的事件。

ACTION_DOWN 一旦在 onTouchEvent 被消费，那么之后的 ACTION_MOVE 和 ACTION_UP 就都会由其处理，结束时间传递。

比如我们在 Activity 的 onTouchEvent 返回 true：

![](https://i.loli.net/2019/02/11/5c60d51909117.png)

红线代表 ACTION_DOWN 事件流向，蓝线代表 ACTION_MOVE 和 ACTION_UP 事件流向。

#### 参考

[图解 Android 事件分发机制](https://www.jianshu.com/p/e99b5e8bd67b)