为了能够很好地回答你的问题,我首先要解释一下 DPI 在 Android 中的工作原理,所以这个答案有点长。
TL;DR:文档是正确的,但是来自 Lint 的警告也是正确的。那就是有一些(有问题的?)设备,mm、in 和 pt 无法正常工作。
Android 中的 DPI
在 Android 中,可以从 DisplayMetrics 类访问两种不同类型的密度度量:
-
densityDpi - 以每英寸点数表示的屏幕密度。此值始终设置为 Android 中可用的通用密度桶之一(例如,Medium/160、High/240、Extra High/320)。
-
xdpi / ydpi - X/Y 维度上每英寸屏幕的精确物理像素。此值与 densityDpi 略有不同的情况并不少见,具体取决于设备的屏幕尺寸和分辨率。
dp 单位是根据 densityDpi 指标计算的,而mm、in 和 pt 单位都是根据 xdpi/ydpi 计算的。
报告值
可以根据设备报告的 densityDpi 和 xdpi / ydpi 值将设备分为四个不同的类别:
- densityDpi 几乎相同,或与 xdpi / ydpi 相同。
- densityDpi 明显小于 xdpi / ydpi
- densityDpi 明显大于 xdpi / ydpi
- xdpi / ydpi 值完全错误。
类别1(密度Dpi与xdpi / ydpi相同)
示例设备:三星 Galaxy Trend、Nexus 4、Nexus 7。
对于这些设备,使用in、mm 或dp 并不重要。如果您绘制一个边为1 in 的正方形和一个边为160 dp 的正方形,它们将是相同的,并且两者在实际屏幕上都大约为1 英寸。
类别 2 和 3(密度 Dpi 不同于 xdpi / ydpi)
第 2 类示例设备: HTC One S、索尼 Xperia V、索尼 Xperia Z Ultra。
第 3 类示例设备:三星 Galaxy S4、索尼 Xperia Z1 , Nexus 5。
对于这些设备, densityDpi 和 xdpi / ydpi 不同,因为 densityDpi 必须设置为可用的密度桶之一。因此,真实的物理 dpi 被四舍五入以匹配最近的存储桶,这就是报告的密度 DPI 值。 Figure 1 in the Supporting Multiple Screens 文档说明了这一点。
这意味着如果你画一个边为1 in 的正方形和一个边为160 dp 的正方形,它们的大小会略有不同。对于 2 类设备,160 dp 正方形会稍微小一些,而对于 3 类设备,它会稍微大一些。如果您拿出尺子并实际测量手机屏幕上的方格,您会发现1 in 方格为 1 英寸,而160 dp 方格会根据类别稍小或稍大。
这是 Android 中密度桶系统的自然结果,但除非您对其工作原理有更深入的了解,否则使用固定 dp 度量绘制的内容在不同手机上可能看起来不同,这可能有点令人惊讶。
类别 4(不正确的 xdpi / ydpi 值)
示例设备:三星 Galaxy Mini、三星 Galaxy S3 Mini。
这些设备的问题更大,它们的密度 Dpi 值很好(它们的真实 dpi 四舍五入到最近的桶),但它们报告的 xdpi / ydpi 值是虚假的。
例如,三星 Galaxy S3 Mini 报告的 xdpi 为 160,密度 Dpi 为 240。屏幕宽度为 480 像素,因此如果 160 dpi 正确,这意味着屏幕宽度为 3 英寸,但实际上屏幕为 2.05 英寸。根据这些数字,手机应报告的实际 xdpi 值为 234。
另一个例子是三星 Galaxy Mini,它也报告 xdpi 为 160,但将密度 Dpi 设置为 120。该屏幕的宽度为 240 像素,因此物理宽度为 1.5 英寸,但实际上屏幕为 1.9 英寸(实际 xdpi 为 126)。
因此,在这些类型的设备上,不可能信任 in、mm、pt 单位,因为它们会导致事物变得太小或太大。
示例
1-3 类
这是我在类别 1、2 和 3 的设备上制作的测试应用程序的三个屏幕截图。根据使用 xdpi 和 ydpi 值,绿色方块被绘制为 1 英寸大,而红色方块被绘制使用 dp (160 dp) 为 1 英寸大。
当用尺子实际测量结果时,在所有这些示例中,绿色方块都是英寸大,而红色方块的大小略有不同,因为它在屏幕截图中可见。
第 4 类
这是第 4 类设备的屏幕截图。绿色和红色方块与前面的示例相同,但这里我还添加了两个方块,一个黄色方块是1 in,一个蓝色方块是72 pt。如屏幕截图所示,除红色方块外的所有方块都具有相同的大小。
当用尺子实际测量结果时,红色方块大约 1 英寸大,而其余方块只有大约 0.67 英寸大。
问题的答案
来自 Lint 的警告指的是 4 类设备返回的 xdpi 和 ydpi 值不正确。由于 xdpi / ydpi 在这些设备上无法信任,因此依赖它们的单元(mm、in、pt)也无法信任。
文档有误吗?
文档不正确,这些单位基于屏幕的物理尺寸。但是,一些有问题的设备会向 Android 报告错误的屏幕物理尺寸 (xdpi / ydpi) 值,然后这些单位也会出错。
为什么 Lint 在使用 pt 时没有警告?
Lint 开发人员可能只是忘记了pt,它和in 和mm 一样有问题。
Lint 推荐使用 dp 的原因是因为这是一个在 Android 中非常频繁使用的单元,所以如果任何设备损坏了 dp 单元,几乎所有应用程序都会看起来很糟糕,它会在设备之前修复曾经投放市场。