一道简单的面试题面试题?
ViewGroup 和 ChildView 同时监听( View.onClick()),哪个会执行?
看完这篇文章一定会理解,如果还不理解请留言
一、责任链模式优点
一提起责任链模式你是不是马上想起OkHttp的拦截器?
用拦截器的思想思考 View 的 事件分发其实整个思路就清晰了。
责任链模式让这个流程非常简洁。理解也非常容易。
二、Android 事件分发机制
0.事件是如何产生的?
大部分的图形界面其实都会使用树形结构,这样层级会比较清晰。逻辑也很简单。
这里要着重说明一个非常重要的点,也是很多开发者容易被忽略的点。事件是如何产生的?理解了这一点,整个流程就非常好理解了。
首先,我们的点击事件,滑动事件,其实都是从硬件传递过来的。这里会涉及硬件,驱动,操作系统等一系列内容,这个不在这里探讨。我们只要知道,系统会把各种操作事件,发送到当前屏幕正在显示的 Activity,这里一定要理解,整个View事件分发的起始位置一定是从Activity开始的,理解了这一点,后面分析事件分发就比较容易了。
事件触发之后传递到 Activity, 然后通过 Activity 通过PhoneWindow 传递到DecorView。
Activity PhoneWindow DecorView 为整个View的跟, 之间的关系可以简单理解为 DecorView 为整个View 树的的跟View, PhoneWindow 就是连接Activity 和 DecorView 的桥梁,这个内容也不是本文展开的重点。
有了跟View 那么整个View 树就可以一点点构建起来了,事件也是这样传递的。
Activity -> PhoneWindow -> DecorView
1. View 树的事件传递
DecorView -> ViewGroup ->ViewGroup-> ... -> View
事件传递的顺序理解之后,我们来看看事件是如何消费的?事件这个传递方向一定是从Activity到跟View 再基于View 的树形结构一个一个的分发到最后的集体的View。
这样的事件分发机制逻辑非常清晰, 如果最后分发到View,如果这个View也没有消费这个事件,那么这个事件会按照反方向回传,最终传回给Activity,如果最后 Activity 也没有处理,本次事件才会被抛弃
一个没有任何View消费的时间。会走一大圈在,大概这个样子
Activity -> PhoneWindow -> DecorView -> ViewGroup -> ViewGroup-> ... -> View
Activity <- PhoneWindow <- DecorView <- ViewGroup <- ViewGroup <- ... <- View
通过这个流程,我们就可以看到View事件分发已经非常清晰了。
这是一个非常简单的 责任链模式 就可以实现。
每个层级各司其职, 如果需要处理就拦截下来自己干,如果不需要处理或者不确定就交给责任链中下一个对象。 这种设计是非常精巧的,上层View既可以直接拦截该事件,自己处理,也可以先询问(分发给)子View,如果子View需要就交给子View处理,如果子View不需要还能继续交给上层View处理。既保证了事件的有序性,又非常的灵活。
具体实现就非常简单了。责任链模式写起来就很容易。Android使用了三个主要方法来实现这个机制。
onInterceptTouchEvent
dispatchTouchEvent
onTouchEvent
Activity 和 View 没有事件拦截:
Activity 一般不会拦截,从设计角度,这个其实是View的分发,如果View需要拦截,可以从View层面去处理就可以,而 Activity 其实一个管家,相当于一个桥梁,这样Activity的逻辑会更清晰一些。
View最为事件传递的最末端,要么消费掉事件,要么不处理进行回传,根本没必要进行事件拦截。
这样我们就能更直白的看懂View事件的传递机制了。
三、 事件分发机制源码
了解了上面这些,还有责任链模式,在开发过程中,如果遇到问题,可以查看源码,具体情况具体分析,就非常容易了。了解了上面的整体流程其实看,源码也非常简单。其实整个源码就是为了实现上面说的内容而基于责任链模式写的,其实不看源码我们自己写一个类似的逻辑也会非常容易。
理解上面的分析其实很多面试题都可以迎刃而解了。
四、 面试题回答
ViewGroup 和 ChildView 同时监听( View.onClick()),哪个会执行?
事件如果没有拦截,就会一层一层传递,最后传递到ChildView 消费掉。
因为是责任链模式,所以不管消费不消费都会返回回去,告诉外层View我消费了,ViewGroup看到ChildView消费了 就会忽略,不做任何事情了。
事件分发面试题还是有一些的,这里没有扩展太复杂,只是想把最最最基础的逻辑讲清楚吗,理解了这个逻辑,再去分析各种面试题都会手到擒来的,希望对你有帮助。