事件分发流程
事件分发对于MontionEvent事件分发。
三个重要方法
- dispatchTouchEnent
用来分发,事件传递到view,该方法一定会被调用 - onInterceptionTouchEvent
判断是否拦截某个事件,如果view拦截某个事件,同一事件周期内,此方法不会被调用 - onTouchEvent
处理事件,消耗当前事件,如果不消耗,同一个事件周期内,当前view不在接受该事件。
初始事件传递
当一个事件产生后,传递给当前Activity,由Activity的dispatchTouchEnent分发事件,具体由Activity的Window来完成。不过Window是抽象类,实现是PhoneWindow类,而PhoneWindow会将事件传递给Decor View。Decor View 一般当前界面的底层view,即setContentView所设置的view的父容器。这样事件传递到根view。
简单流程
ViewGroup 接受到一个点击事件,会调用dispatchTouchEnent,如果ViewGroup的onInterceptionTouchEvent方法返回true,表示拦截当前事件,事件传递给ViewGroup处理,如果onInterceptionTouchEvent返回false,不拦截当前事件,当前事件传递给子view,子view的dispatchTouchEnent被调用,重复上面操作。
具体流程
- 如果事件传递到view,该view的onTouchEvent返回false,没有处理,事件传递给父view,由父view的onTouchEvent处理,如果所有view都没有处理该事件,最终由Activity的onTouchEvent处理该事件。
- 如果其中一个view拦截事件,如果不处理ACTION_DOWN事件,后续事件不会传递给该view,事件由父view处理;如果处理ACTION_DOWN事件,不处理其他事件,这些事件消失,但会传递给Activity处理。
方法requestDisallowInterceptTouchEvent可以干预父事件的分发过程。阻止ViewGroup对其MOVE或者UP事件进行拦截。
整个事件分发过程中,ACTION_DOWN事件能否找到目标组件(最终处理事件的组件),对事件分发流程很重要。