【Android 事件分发】事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) 【Android 事件分发】事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup ) 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 一 ) 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 二 ) 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 ) 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 ) 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )
- Android 事件分发 系列文章目录
- 前言
- 一、ViewGroup | dispatchTransformedTouchEvent 方法返回值含义
- 二、记录被消费的触摸事件
- 三、触摸事件没有被消费的调用链分析
- 四、触摸事件被拦截的调用链分析
- 五、ViewGroup 事件分发相关源码
- 六、View 事件分发相关源码
- 总结
接上一篇博客 【Android 事件分发】事件分发源码分析 ( View 事件传递机制 ) , 继续分析 ViewGroup 的事件分发机制后续代码 ;
Activity 事件传递 , 最终调用到了 ViewGroup 的 dispatchTouchEvent 方法 , 在该方法中有调用了 View 的 dispatchTouchEvent 方法 ;
View 的 dispatchTouchEvent 调用完毕后 , 会返回 true 或 false 结果 ;
那么继续回到 ViewGroup 的 dispatchTransformedTouchEvent 方法 , 在该方法中 , 也就是遍历 ViewGroup 子组件时 , 调用遍历的子组件 View 的 dispatchTouchEvent 方法 , 处理相关触摸和点击相关的操作 ;
本博客继续分析 ViewGroup 的后续调用链 ;
一、ViewGroup | dispatchTransformedTouchEvent 方法返回值含义在 ViewGroup | dispatchTouchEvent 方法中 , 调用 ViewGroup | dispatchTransformedTouchEvent 方法进行事件的转发 , 主要是遍历子组件调用子组件的触摸方法 ;
在 ViewGroup | dispatchTransformedTouchEvent 方法中 , 调用了 View 子组件的 View | dispatchTouchEvent 方法 , 该方法返回 true/false , 那么对应的 ViewGroup | dispatchTransformedTouchEvent 方法也会返回相同的值 ;
由下面的代码可知 , handled 是子组件 child.dispatchTouchEvent 调用返回值 , 返回结果就是 handled , 然后有将该值直接返回 , 说明 View 子组件的 dispatchTouchEvent 调用结果 , 就是 ViewGroup 的 dispatchTransformedTouchEvent 方法的返回结果 ;
ViewGroup | dispatchTransformedTouchEvent 方法的返回值含义 :
① 如果返回 true , 证明 子组件 View 已经将事件消费完毕 , 后续不需要再继续执行遍历了 ; ② 如果返回 false , 证明 子组件并没有将事件消费 , 后续还可以进行触发 ;
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits) {
...
if (child == null) {
// 被遍历的 child 子组件为空
// 调用父类的分发方法
handled = super.dispatchTouchEvent(event);
} else {
// 被遍历的 child 子组件不为空
final float offsetX = mScrollX - child.mLeft;
final float offsetY = mScrollY - child.mTop;
event.offsetLocation(offsetX, offsetY);
// 子组件分发触摸事件
// 此处调用的是 View 组件的 dispatchTouchEvent 方法 ;
handled = child.dispatchTouchEvent(event);
event.offsetLocation(-offsetX, -offsetY);
}
return handled;
}
...
}
}
二、记录被消费的触摸事件
如果 ViewGroup | dispatchTransformedTouchEvent 方法的返回值为 true , 则会触发记录已经被消费的事件的分支 ; 如果返回 false , 则不会触发 ;
// 正式开始分发触摸事件
// 处理以下两种情况 :
// ① 情况一 : 子控件触摸事件返回 true
// ② 情况二 : 子控件触摸事件返回 false
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
记录时 , 同时会创建 TouchTarget , 并赋值给 ViewGroup | dispatchTouchEvent | newTouchTarget 局部变量 ;
// 记录消费事件
// 添加触摸目标
newTouchTarget = addTouchTarget(child, idBitsToAssign);
调用 addTouchTarget 方法 , 创建被消费的事件 , 并将创建的值赋值给了 ViewGroup | mFirstTouchTarget 成员 ; 第一次消费事件被赋值 ;
private TouchTarget addTouchTarget(@NonNull View child, int pointerIdBits) {
final TouchTarget target = TouchTarget.obtain(child, pointerIdBits);
target.next = mFirstTouchTarget;
mFirstTouchTarget = target;
return target;
}
完整代码如下 :
@UiThread
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
...
// 正式开始分发触摸事件
// 处理以下两种情况 :
// ① 情况一 : 子控件触摸事件返回 true
// ② 情况二 : 子控件触摸事件返回 false
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
// Child wants to receive touch within its bounds.
// 如果返回值为 true , 说明该事件已经被消费了
// 此时记录这个已经被消费的事件
mLastTouchDownTime = ev.getDownTime();
if (preorderedList != null) {
// childIndex points into presorted list, find original index
for (int j = 0; j
关注
打赏
- 【Android Gradle 插件】Gradle 自定义 Plugin 插件 ③ ( 自定义插件作用 | Android Gradle 插件的扩展 | 自定义 Extension 扩展 )
- 【Android Gradle 插件】Gradle 构建生命周期 ③ ( BuildListener 构建监听器 | TaskExecutionGraphListener 任务执行图监听器 )
- 【Android Gradle 插件】Gradle 构建生命周期 ② ( Gradle 类的添加构建生命周期监听器函数 | Gradle#addListener 函数 )
- 【Android Gradle 插件】Gradle 构建生命周期 ① ( 分析构建脚本 | 执行初始化配置 | 执行 Gradle 任务 | Project#beforeEvaluate 函数 )
- 【Android Gradle 插件】自定义 Gradle 任务 ⑨ ( 控制 Gradle 执行任务顺序 | Task#finalizedBy 函数 | 控制 Gradle 执行任务顺序示例分析 )
- 【Android Gradle 插件】自定义 Gradle 任务 ⑧ ( 控制 Gradle 执行任务顺序 | Task#shouldRunAfter 函数 | 三个函数使用场景对比 )
- 【Android Gradle 插件】自定义 Gradle 任务 ⑦ ( 控制 Gradle 执行任务顺序 | Task#dependsOn 函数 | Task#mustRunAfter 函数 )
- 【数学分析】集合 ① ( 集合概念 | 集合表示 | 常用的数集合 | 集合的表示 )
- 【数学分析】学科简介 ( 初等数学缺陷 | 微分与积分 | 学习数学分析的目的 | 数学分析与高等数学对比 )
- 【Android Gradle 插件】自定义 Gradle 任务 ③ ( Gradle 自定义任务创建方法 Project#task 函数 | Task#doFirst 函数用法 )