说说 pandora 的视图调试功能


本文原文在 https://wkmcyz.notion.site/pandora-7addb6e57ddc4aa9a19e83a3d4186973 ,复制到 cnblog ,格式不太对,朋友们见谅。

简介

本篇简单介绍一下 pandora 的视图调试相关的功能是怎么实现的。

笔者今天写东西的时间不多,所以行文仓促,加之本身了解不够全面,所以可能会有些地方不太有逻辑或者没讲清楚,还望见谅。

视图选择功能

通过单击选中一个 view 是怎么实现的

这里笔者是这样思考的 : 从功能的实际效果分析,点击了一个位置( x , y )以后,选中的是当前 view 树中包含该(x , y)坐标的可见的叶节点。所以我们可以从当前 view 树的根节点进行遍历以进行查找,在每一层节点重复这样的选择:

  1. 遍历该层的所有子节点判断当前的点击事件是在哪个子 view 的绘制区域内。这里可能会是多个子 view 同时包含了该点,那么就需要判断究竟哪个子 view 是当前最靠前的(一般来说就是 zIndex 最大的,或者是最后绘制的。)得到该节点 view ,如果该 view 有子节点的话,重复本操作;如果没有的话,就是我们最后得到的 view。

那么可以参考源码查看是否是我们想象中的效果,查看如下文件:

https://github.com/whataa/pandora/blob/master/pandora-core/src/main/java/tech/linjiang/pandora/inspector/ElementHoldView.java

https://github.com/whataa/pandora/blob/master/pandora-core/src/main/java/tech/linjiang/pandora/inspector/OperableView.java

因为时间原因,笔者只简单说下理解,源码不做赘述了。可以看到代码里原作者先遍历 decorView 将所有的叶节点 view 缓存下来,然后在点击的时候遍历这个缓存匹配。

但是这里的匹配规则是 :当前缓存的 view 中第一个包含该 (x , y) 的,这里可能会有一个问题:

  • 如果点击的区域被两个 view 包含的话,第一个 view 先被添加,第二个 view 后被添加,而第一个 view 的 translation 比第二个 view 要大,那么从代码来看应该会选中第二个 view ,而实际上应该选中第一个 view 。

选中一个 view 后再选中一个 view ,显示出来两个 view 的距离

该问题比较简单,基于上面的 "单击选中" 的功能,我们可以选中两个 view ,在选中第二个 view 的时候,计算出两者在屏幕上的宽高间距差值即可,

通过拖拽改变 view 的位置需要哪些关键的 API?

因为我们已经获得了 view 对象,所以我们可以通过改变其 translationX / translationY 来进行 view 的移动,同时需要设置其 parent 不对子 view 进行裁切。不过查看代码发现这里又有一个问题:

  • 代码中并没有设置 parent 的 clipChildren 属性,这样的话子 view 会无法移出父 view 。

查看视图层级功能

该功能就是从 decorView 开始遍历 view 树,获取所有 view 的各种属性即可。