二、Activity 中的事件分发机制
Activity 中包含两个事件分发与处理的方法,分别是:
- boolean dispatchTouchEvent(MotionEvent ev):事件分发
- boolean onTouchEvent(MotionEvent event):事件消费
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
第一步是判断事件如果是点击事件,则调用 onUserInteraction 方法,该方法的方法体为空,可以重写这个方法,用于处理一些交互问题。
第二步是调用了 Window 的 superDispatchTouchEvent 方法,如果返回 true,则表示此事件已被消费,结束此次分发流程,false 则继续调用该 Activity 的 onTouchEvent 方法处理该事件。
总结一下,事件进入 Activity的dispatchTouchEvent 开始分发,首先会将该事件传递给该页面的 ViewGroup,ViewGroup 如果消费了该事件,则分发结束,未消费则继续调用 Activity#onTouchEvent 方法处理事件,流程如图:
三、ViewGroup 中的事件分发
ViewGroup 中包含三个事件分发相关的方法:
- dispatchTouchEvent(MotionEvent ev):
- onIntercepTouchEvent(MotionEvent ev):
- onTouchEvent(MotionEvent ev):
1、事件首先会进入 dispatchTouchEvent 方法开始分发。
2、dispatchTouchEvent方法通过调用onInterceptTouchEvent 方法判断是否需要拦截事件。
- 2.1、如果需要拦截(方法返回 true),则表示当前 ViewGroup 希望处理该事件,或者不希望子 View 处理该事件,此时将直接调用 onTouchEvent 方法。
- 2.2、如果不需要拦截,则将该事件传递给子 View 的 onTouchEvent 方法,或者子 ViewGroup 的 dispatchTouchEvent 方法。
3、onTouchEvent 方法, 该方法用于消费事件,返回值表示是否已消费,在两种情况下会被调用:onInterceptTouchEvent 方法确认需要拦截该事件以及子 View/ViewGroup 未消费该事件。
- 3.1、如果该方法返回 true,则表示事件已消费,此次事件分发就成结束;
- 3.2、如果返回 false,则表示未消费该事件,会继续调用父 ViewGroup 或 Activity 的 onTouchEvent 方法。
ViewGroup的事件分发机制如下:
四、View 中的事件分发机制
View 中包含如下两个用于处理事件分发相关的方法:
- dispatchTouchEvent(MotionEvent event)
- onTouchEvent(MotionEvent event)
ViewGroup 会将事件传递给 dispatchTouchEvent 方法,由于不是 ViewGroup,不需要考虑向下传递事件的逻辑,所以 View 中的事件处理流程很简单。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!