谈谈 android 事件分发机制--标准答案

2020-07-24  本文已影响0人  一方乌鸦

最详细的讲解:
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回溯

上一篇 下一篇

猜你喜欢

热点阅读