事件分发机制(一)--Activity
2023-09-15 03:54:08
「这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战」
- 被分发的对象
按下、滑动、抬起、取消这几种事件组成了一个事件流。事件流以按下为开始,中间可能有若干次滑动,以抬起或取消为结束。事件流会以一定顺序传递给 Activity 内符合条件的所有控件 ,若控件设置了点击事件或某个事件的监听,控件就会对这个事件进行消费,就停止进一步的传递。
- 事件的传递机制
事件的传递机制主要包含三步:活动分发、控件分发和消费事件 。对于触摸事件,系统的触摸分发机制会检查当前控件的触摸模式和事件的类型来决定是消费还是传递 ,若控件没有消费,则系统将事件传递到控件所属的 ViewGroup 中,ViewGroup 中存在多个控件,需要通过判断该控件是否拦截 或消费 这个事件来决定是否要传递给下面的控件 。
- 布局分发
当事件分发到达某个 ViewGroup 的时候,则会进入 ViewGroup 的布局分发阶段,主要包括三个步骤 :
- 1. 拦截阶段
在这个阶段,ViewGroup 根据自己是否设置了拦截器(拦截器是指实现了 onInterceptTouchEvent 方法,该方法返回 true,则拦截事件)来决定是直接处理事件还是交给子控件处理,拦截器通常用在两个控件需要同时消费事件的情况 ,如 ,手势处理控件与触摸滚动控件同处一个容器控件,同时消费一个事件 。
- 2. 处理事件阶段
处理阶段是事件分发的核心,ViewGroup 根据自己是否能处理这个事件来决定是直接消费事件还是交给子控件处理,如果ViewGroup 本身可以处理的话,这里也可以拦截事件,消费事件,或者在默认情况下传递事件。对于一个 ViewGroup 来说,如果有子控件已经消费了这个事件,则 ViewGroup 一般不会再消费事件,而是传递事件。控件默认情况下都会消费事件。
- 3. 分发给子控件
当 ViewGroup 没有消费这个事件时,就会分发给子控件来消费事件,事件分发顺序与子控件的顺序一致。ViewGroup 中子控件的绘制顺序可以参考该 ViewGroup 的 addView 方法和 addChild 方法,添加到后面的控件会被绘制在上面。
- 事件分发流程
可以总结出一个事件分发流程图:
- 事件消费过程中的注意事项
-
绝对位置 与 相对位置 的区别:绝对位置控件中的坐标都是以控件自己的左上角为原点来计算的 ,而相对位置控件的坐标是相对于父控件的左上角来计算的 。触摸事件的坐标都是以屏幕左上角为原点来计算的 。
-
普通 ViewGroup 与 Scroll ViewGroup 的区别:普通 ViewGroup 不会阻止触摸事件的传递,并且不会对触摸事件进行消耗,但Scroll ViewGroup 既会阻止触摸事件的传递,又会对触摸事件进行消耗。
-
事件的生命周期:每个事件的生命周期分为 ** ACTION_DOWN、ACTION_MOVE 和 ** ACTION_UP** 三个阶段** ,每个阶段可以调用不同的方法来处理事件。
- 事件分发的使用场景
事件分发的场景非常广泛,比如手势识别、拖动控件、点击控件等。比如手势识别,需要知道手指触摸屏幕的位置和移动轨迹 ,拖动控件,需要知道手指触摸的位置和移动的方向 ,点击控件,需要知道手指触摸的位置 。