最详细的讲解:
https://www.jianshu.com/p/38015afcdb58/
当被问到这个问题时,如何简洁并完整的回答这个问题?
现在一般会给个场景
A 嵌套 B ,B 嵌套 C,从 C 中心按下,一下滑出到 A,描述事件分发的过程(包含ACTION_CANCEL 的调用时机)
todo 标准答案
下面是通俗答案
事件分发的的本质是将Touch事件 MotionEvent 传递到某个具体的View,以及处理事件的过程。
MotionEvent按照从Activity到ViewGroup再到View的顺序传递。
由dispatchTouchEvent() 、onInterceptTouchEvent()和onTouchEvent()三个方法协作完成。
1.Activity
MotionEvent由WMS分发给应用程序后,从Activity.dispatchTouchEvent()开始,调用super.dispatchTouchEvent(),调用window.superDispatchTouchEvent(),再调用DecorView.superDispatchTouchEvent(),事件就传递到DecorView。
MotionEvent通过在DecorView中调用ViewGroup.dispatchTouchEven传递到它所持有的ViewGroup,如果Activity中super.dispatchTouchEvent返回的是false,那么会执行Activity.onTouchEvent(),并将onTouchEvent结果返回。
如果Activity中super.dispatchTouchEvent()返回为true,表示事件被子View消费,不执行Activity.OnTouchEvent().如果Activity不调用super.dispatchTouchEvent,那么事件就不会往子View传递。
2.ViewGroup
MotionEvent从ViewGroup.dispatchTouchEvent()开始传递,先通过ViewGroup.onInterceptTouchEvent()
判断是否需要拦截事件。
这里有两个分支,如果onInterceptTouchEvent返回为false,则事件向子View传递,通过遍历找到被点击的子View,调用子View的dispatchTouchEvent, 并将结果返回。
如果onInterceptTouchEvent为true或者点击范围不在任何一个子View中(点击空白),则会调用父类View.dispatchTouchEvent, 再执行ViewGroup作为View的onTouch,onTouchEvent,performClick,onClick。
3.View
MotionEvent从View.dispatchTouchEvent开始传递。
如果onTouchListener不为空,调用onTouchListener.onTouch(),如果onTouch返回true,事件被消费,结果向Activity回溯,不再调用onClick()。
如果onTouch返回false,则会调用自身onTouchEvent(),onTouchEvent再调用performClick。在调用onClickListener.onClick(),dispatchTouchEvent返回true,结果向Activity回溯
网友评论