聊一聊android 原生怎么实现跨层级传递事件

场景:

层级

这个是正常布局 A 包含 B B包含C 这样只要正常点击C C是能正常接收到事件的。

如果层级不变,变成如下

也就是C超出了他的父节点B,这个时候点击C,C是接收不到事件的。因为他的父节点没有收到事件,所以也就不会传递给他。

我的需求就是想在这种情况下C也能正常处理事件。怎么办?

我的第一个方案:

布局都是直接子View,都只有一个子View,我的做法是直接透传。类似下面的这种。

js 复制代码
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        View view = getChildAt(0);
        view.dispatchTouchEvent(ev);
   }

这种在B没有做任何转换的时候是没有问题,如果B做了缩放操作,就会有问题。官方代码里面是对这些缩放做过处理的。因为我们没有走官方的就会有问题。

我的第二个方案:

对于每个业务布局层次基本是固定的,我们可以直接遍历,找到我们想要操作的View,比如我们一直向下查找,找到组件C,然后直接传递event 跟C。这样处理也需要二次处理event。比如我们经常用 getX getY api,这个是相对于的,但是我们直接传递A的event,是相对于A的。所以event的location需要转换成相对于C的,再传递给C才能保证在不改变C的事件处理逻辑的情况下,让C能正常处理手势。

类似下面这样 根据C的旋转角度,计算点击点相对于自身的位置,修改location属性

js 复制代码
                      float evGlobalX = ev.getRawX();
                      float evGlobalY = ev.getRawY();
                      if(view.getRotate() == 90){
                          ev.setLocation((evGlobalY - topLeftPosition[1])/child.getScaleY(),(topLeftPosition[0] - evGlobalX)/child.getScaleX());
                      }else if(view.getRotate() == 0){
                          ev.setLocation((evGlobalX - topLeftPosition[0])/child.getScaleX(),(evGlobalY - topLeftPosition[1])/child.getScaleY());
                      }else if(view.getRotate() == 180){
                          ev.setLocation((topLeftPosition[0] - evGlobalX)/child.getScaleY(),(topLeftPosition[1] - evGlobalY)/child.getScaleX());
                      }else if(view.getRotate() == 270){
                          ev.setLocation((topLeftPosition[1] - evGlobalY)/child.getScaleX(),(evGlobalX - topLeftPosition[0])/child.getScaleY());
                      }
                      targetView.dispatchTouchEvent(ev);
相关推荐
Jinkxs2 小时前
Python基础 - 初识内置函数 Python自带的便捷工具
android·java·python
私人珍藏库2 小时前
【Android】VLLO-韩国热门手机剪辑APP
android·app·工具·软件·多功能
Cloud_Shy6183 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第六章 Item 40 - 43)
android·开发语言·人工智能·笔记·python·学习方法
AFinalStone4 小时前
Android12 U盘插拔链路源码全解析(五):Framework层(下) StorageManagerService
android·frameworks
林九生5 小时前
【实用技巧】MySQL 绿色版一键路径更新脚本详解 —— update_path.bat 深度解析
android·数据库·mysql
故渊at6 小时前
第十三板块:Android 综合架构与未来演进 | 第三十一篇:Android 架构演进与 Fuchsia OS 的挑战
android·架构·宏内核·微内核·fuchsia·ipc 性能博弈
aqi006 小时前
一文速览 HarmonyOS 6.1.1 推出的十个新特性
android·华为·harmonyos·鸿蒙·harmony
matrixmind16 小时前
aiomysql:异步场景下的 MySQL 驱动
android·数据库·mysql·其他
随遇丿而安6 小时前
第8周:弹窗 / 提示组件全功能与弹窗优化
android
zh_xuan6 小时前
诡异Bug:输入框删除字符,却越删越多
android·bug