安卓事件分发机制

首先从view的树状结构谈起:

从外到里分别为:window,phonewindow,decorview ,rootview ,viregroup,view

Window是一个抽象类,是所有视图的最顶层容器,视图的外观和行为都归他管,不论是背景显示,标题栏还是事件处理都是他管理的范畴,但是它是抽象类 不可以直接调用

 PhoneWindow 作为 Window 的唯一亲儿子(唯一实现类),自然就是 View 界的皇帝了,PhoneWindow 的权利可是非常大大,不过对于我们来说用处并不大,因为皇帝平时都是躲在深宫里面的,虽然偶尔用特殊方法能见上一面,但想要完全指挥 PhoneWindow 为你工作是很困难的

DecorView 是 PhoneWindow 的一个内部类,其职位相当于小太监,就是跟在 PhoneWindow 身边专业为 PhoneWindow 服务的,除了自己要干活之外,也负责消息的传递,PhoneWindow 的指示通过 DecorView 传递给下面的 View,而下面 View 的信息也通过 DecorView 回传给 PhoneWindow。

接着:view的事件分发机制 ,其实是一种责任链的模式

举一个例子来进行讲解:

Activity-phonewindow-decorview-rootview-viewgroup-view

安卓事件分发机制_第1张图片

安卓事件分发机制_第2张图片

PS: 从上表可以看到 Activity 和 View 都是没有事件拦截的,这是因为:

Activity 作为原始的事件分发者,如果 Activity 拦截了事件会导致整个屏幕都无法响应事件,这肯定不是我们想要的效果。

View最为事件传递的最末端,要么消费掉事件,要么不处理进行回传,根本没必要进行事件拦截。

 

下面 我们来分析一下:如果点击view1 ,整个事件分发的流程

首先:activity 会调用dispatchTouchEvent向下 传递事件 ,rootview 同样调用dispatchTouchEvent向下传递事件,调用onInterceptTouchEvent 判断是否进行拦截,如果拦截结果返回为true 就代表自身要消费这个事件,就不会往下传递,就会调用自身的onTouchEvent 方法. 如果不进行拦截 则 onInterceptTouchEvent 方法返回结果为false,则继续向下传递 。

接下来的viewgroup 与 rootview 的工作流程一直,判断是否拦截,如果返回为true 则自己消费,调用自身的 onTouchEvent 方法最后传递给 view1,view1 先调用dipatchTouchEvent方法,然后调用ontouchEvent 方法,根据返回值判断,返回值为true 则代表这个view1 消费了这次的事件,如果返回结果为false ,则会一层一层的反向 向上传递,如果都没有被消费,则此次点击事件 就没有事件响应

View 相关

dispatchTouchEvent 是事件分发机制中的核心,所有的事件调度都归它管。不过我细看表格, ViewGroup 有 dispatchTouchEvent 也就算了,毕竟人家有一堆 ChildView 需要管理,但为啥 View 也有?这就引出了我们的第一个疑问。

Q: 为什么 View 会有 dispatchTouchEvent ?

A: 我们知道 View 可以注册很多事件监听器,例如:单击事件(onClick)、长按事件(onLongClick)、触摸事件(onTouch),并且View自身也有 onTouchEvent 方法,那么问题来了,这么多与事件相关的方法应该由谁管理?毋庸置疑就是 dispatchTouchEvent,所以 View 也会有事件分发.

view的事件分发默认顺序如下:

安卓事件分发机制_第3张图片

 

 

 

 

 参考的文章链接为:http://www.gcssloop.com/customview/CustomViewIndex/ 这是一个非常完整的自定义view的系列文章

你可能感兴趣的:(安卓事件分发机制)