密度,设备和片状测试
写一个撰写的自定义布局是微调应用程序UI的外观的好方法,而且并不像看起来那样令人生畏。写下自定义逻辑后,您还应该为其编写测试!但是,在编写这些测试时,您可能会发现这些测试的某些奇怪行为有时会通过,有时会失败,具体取决于您正在运行的设备。
让我们跳入分析一个简单(但片状!)测试以验证组合布局的行为:
该测试的目的是检查一个柱子
包含6垫片
S每个10DP高,最终为60dp。
这柱子
检索了的坐标修改器
验证放置的位置,并从类似地检索到设备屏幕的密度局部
。
所得的坐标以整数数量的像素表示,因此我们将预期的60DP转换为像素roundtopx()
。
所有这些步骤似乎都足够无害,所以让我们进行测试。成功……或者也许是失败。该测试可能会或可能不会通过,具体取决于我们正在运行测试的设备。让我们仔细看看发生了什么。
PX与DP与SP
不同的设备具有不同的物理屏幕(有些设备可能具有多个),这意味着它们可以具有不同的显示器大小和不同的显示密度。在许多设备上,用户还可以使用“显示大小”选项更改有效的显示密度自己。
为了确保用户界面在不同设备之间具有一致的明显大小,您应该指定一般UI组件的尺寸使用密度无关的像素或DP。对于文本,您应该使用可扩展的像素或SP,以考虑用户首选的文本大小。
JetPack Compose具有内置的DP
类型和相关方法,它使用一个密度
目的。这密度
对象(可以检索到局部
在一个@composable
功能)由UI运行的设备确定。密度密度
是应用于DP值的浮点缩放系数。A密度密度
1.0的因子意味着1DP将转换为1PX,而A密度密度
2.0因子意味着1DP将转换为2Px。对于某些现实值:Pixel手表的默认密度系数为2.0,Pixel 7 Pro的默认因子为2.625,而4K Android TV的默认密度系数为4.0。
分步布局
考虑到此信息,让我们逐步了解如何计算测试中的布局。
这柱子
将在垂直柱中单一逐一布置其所有子女,因此其大小将是其孩子大小的总和。
每一个柱子
6个孩子是一样的:垫片
那是10dp高。当。。。的时候垫片
测量,其指定的大小从DPS转换为像素,其结果的大小将是一个整数数量像素。
这是针对每个垫片
s,并且由于每个都相同,因此柱子
像素中的高度是任何特定高度的6倍垫片
。
通过一个示例工作:
如果密度系数为2.0,则每个垫片
将有20px的高度柱子
高度为120px。这与我们的预期高度相符Roundtoint(60 * 2.0)= 120px
。
这种转换很简单,由于密度是整数,我们不必圆形。但是,密度可能不是整数!设备的默认密度可能是多种非启动值,并且根据用户的设置,同一设备可以更改此数字。
让我们再试一次,这次的缩放系数为1.75。现在每个垫片
将有一个高度圆点(10 * 1.75)= 18px
, 所以柱子
将有一个高度18 * 6 = 108px
。这与我们预期的高度不同Roundtoint(60 * 1.75)= 105px
,,,,所以我们的测试将失败。因为每个高度垫片
被四舍五入18px,柱子
最终比我们原本预期的高3px。尝试转换回DP进行比较也无济于事:108px刚好超过61.7dp,所以我们的柱子
最终比我们预期的高1.7DP。
结论
虽然上面的测试乍一看似乎没有任何问题,但根据测试正在运行的设备,它可能会通过或失败。构图中的键入DP值有助于确保API使用正确的单元,但它们不会更改单位如何使用和转换为向用户显示组件的基本过程。根据设备和密度因子,中间舍入意味着尺寸值可能不会很好地乘。A柱子
与6垫片
每个10dp高的S可能不高60dp。真正的行为是柱子
每个的高度应是每个圆形高度的6倍垫片
在像素中:
如果您正在编写自定义布局并测试它,请注意不同的设备密度如何影响舍入的方式,以可能引人注目的方式累积。然后,要么编写来解释并验证该行为的测试,要么通过不取决于确切的测量值而允许一定的错误余量。否则,当跨不同的模拟器或物理设备运行时,此舍入可能会导致自定义布局的测试令人沮丧地具有不同的行为。