1. dispatchTouchEvent 分发
- 首先调用的方法,Activity、ViewGroup、View都有,各自实现不同。
- 拦截、处理等方法都是在此方法中调用。
- 用于分发事件。
2. onInterceptTouchEvent 拦截
- ViewGroup独有的方法。
- 用于决定是否拦截事件,true=拦截,自己处理,不再下发给子View。
- 默认不拦截。
3. onTouchEvent 处理
- 用于处理点击事件。
- Activity、View的方法,各自实现不同。
4. Activity
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
- getWindow().superDispatchTouchEvent(ev)。
- getWindow() = PhoneWindow,PhoneWindow中调用的是DecorView的方法,DecorView是个ViewGroup,它的子View就是界面添加的布局。
- 即Activity将事件下发到了ViewGroup处理。
- ViewGroup处理后返回true的话,则分发结束。
- ViewGroup处理后返回false的话,则调用Activity的onTouchEvent方法。
5. ViewGroup
- 先调用onInterceptTouchEvent方法判断是否拦截事件。
- 子View可以调用父View的requestDisallowInterceptTouchEvent方法来不允许父View拦截事件,但对DOWN事件无效,因为DOWN事件会重置FLAG_DISALLOW_INTERCEPT标示。
- 所以如果子View想通过此方法来阻止父View拦截事件,只能在DOWN事件执行完后再调用,不然就算调用了也无效,因为值会在DOWN事件执行后被重置。
- 一旦DOWN事件被拦截,则后续事件都会被拦截,且不再调用onInterceptTouchEvent方法判断。
- ViewGroup拦截了事件自己处理时,是调用super.dispatchTouchEvent(event)方法处理,即View中的dispatchTouchEvent方法。
- 不拦截则交给子View处理,没有子View时也是自己处理。
- 子View处理后返回false,则ViewGroup还是调用super.dispatchTouchEvent(event)自己处理,如果ViewGroup也返回false,即是之前Activity中getWindow().superDispatchTouchEvent(ev)返回false的情况,此时Activity的onTouchEvent被调用。
6. View
- 收到事件后,先判断有没有注册OnTouchListener,如果注册了,则会先调用listener.onTouch方法。
- 如果listener.onTouch方法返回true,则事件结束分发。
- 没有注册OnTouchListener或listener.onTouch返回false,则执行onTouchEvent方法。
- 如果View是disable的,则会直接返回clickable,不会执行performClick方法。
- 如果View是enable的,而clickable是false,则直接返回false。
- 如果enable和clickable都是true,则会在ACTION_UP调用时调用performClick方法并返回true。
- 如果OnClickListener不为null,则mOnClickListener.onClick方法会被调用。