文档说 160 dp(与密度无关)等于 1 英寸。72 pt 也是 1 英寸。所以我不明白为什么 android 定义一个 dp 测量,而它似乎与点工作相同。有人能解释一下吗?如果可以使用 pt,为什么还要使用 dp?
7 回答
Android 文档曾经错误地指出,无论屏幕密度如何,160 dp 始终等于 1 英寸。这被报告为一个错误,已被接受并更新了文档。
从更新的文档中:
160 dp 并不总是等于 1 英寸,它会随着不同的屏幕尺寸和密度而变化。在密度为 160dpi (mdpi) 的屏幕上,160 dp 将等于 1 英寸。
无论屏幕密度如何,1 pt 始终等于 1/72 in。
Android 文档在这里。
更新:
我做了一个小应用程序来尝试验证不同的尺寸。看起来上面的内容是正确的,至少在我的 HTC Aria 上显示时是这样。这是一个屏幕截图:
有趣的是,这些尺寸在 Eclipse 图形编辑器中并不完全匹配。dp 和 sp 大小会根据屏幕大小和编辑器中的分辨率而波动。以下是编辑器的一些截图(左边是 2.7in QVGA 滑块,右边是 10.1in WXGA,已剪辑):
看看这些编辑器渲染是否与实际设备匹配会很有趣。任何人都可以验证这些尺寸吗?我会在下面附上我的 xml,以防有人想帮忙。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="22sp" android:padding="5sp" android:text="160dp"></TextView>
<View android:id="@+id/view1" android:layout_height="20dip" android:layout_width="160dp" android:layout_marginLeft="20sp" android:background="#FF22FF22"></View>
<TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="22sp" android:padding="5sp" android:text="72pt"></TextView>
<View android:id="@+id/view2" android:layout_height="20dip" android:layout_width="72pt" android:layout_marginLeft="20sp" android:background="#FF22FF22"></View>
<TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="22sp" android:padding="5sp" android:text="1in"></TextView>
<View android:id="@+id/View01" android:layout_height="20dip" android:layout_width="1in" android:layout_marginLeft="20sp" android:background="#FF22FF22"></View>
<TextView android:layout_width="wrap_content" android:textSize="22sp" android:layout_height="wrap_content" android:text="160sp" android:padding="5sp" android:id="@+id/TextView01"></TextView>
<View android:layout_marginLeft="20sp" android:layout_width="160sp" android:id="@+id/View04" android:background="#FF22FF22" android:layout_height="20dip"></View>
<TextView android:layout_width="wrap_content" android:textSize="22sp" android:layout_height="wrap_content" android:padding="5sp" android:id="@+id/TextView02" android:text="160px"></TextView>
<View android:layout_marginLeft="20sp" android:id="@+id/View03" android:background="#FF22FF22" android:layout_height="20dip" android:layout_width="160px"></View>
<TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="22sp" android:padding="5sp" android:text="25.4mm"></TextView>
<View android:id="@+id/View02" android:layout_height="20dip" android:layout_marginLeft="20sp" android:background="#FF22FF22" android:layout_width="25.4mm"></View>
</LinearLayout>
编辑:在 John 的示例中添加了另外 2 个设备。左侧是三星 Nexus S (OS 2.3.3)。右侧是三星 Galaxy Tab 10.1 (OS 3.1)。没有模组。
在 Nexus S 上,160dp 略大于 1 英寸。所有正常的物理单位(in、mm、pt)都是相同的大小。我用尺子测量了它,160 dp 的条比它应该大了大约 1 毫米。虽然物理单位比应有的短 1 毫米。
在制表符上,所有条形都完全相同,比我用尺子测量的长 1 毫米。
文档说 160 dp(与密度无关)等于 1 英寸。72 pt 也是 1 英寸。
这里的细微差别是 160 dp
(或dip
)大约是1 英寸,而 72pt
正好是1 英寸。不同之处在于android如何将两个单位转换为像素,这取决于设备的屏幕密度。
单曲dp
是px
设备上 160 dpi 的单曲。Android 使用设备落入的“密度桶”,并乘以一个缩放器以转换dp
为px
.
Bucket | DPI | Scaler
---------------------
ldpi | 120 | 0.75
mdpi | 160 | 1.00
tvdpi | 213 | 1.33
hdpi | 240 | 1.50
xhdpi | 320 | 2.00
xxhdpi | 480 | 3.00
dp
转换px
为以下公式:dp * scaler = px
.
在任何屏幕密度上,单张pt
都恰好是 1/72 英寸。Android 转换pt
为px
使用设备屏幕的精确 dpi(xdpi 和 ydpi)。
pt
转换px
为以下公式:pt / 72 * dpi = px
.
所以我不明白为什么 android 定义一个 dp 测量,而它似乎与点工作相同。有人能解释一下吗?如果可以使用 pt,为什么还要使用 dp?
举个例子,在 160 dpi 设备上显示 160dp
和 72 。pt
一个 160 dpi 的设备属于 mdpi 密度桶,缩放比例为 1.0。使用上面的公式转换为px
.
160 dp * 1.0 = 160 px
72 pt / 72 * 160 = 160 px
在 170 dpi 的设备上呢?一个 170 dpi 的设备属于 mdpi 密度桶,缩放比例为 1.0。
160 dp * 1.0 = 160 px
72 pt / 72 * 170 = 170 px
在 150 dpi 的设备上呢?一个 150 dpi 的设备属于 mdpi 密度桶,缩放比例为 1.0。
160 dp * 1.0 = 160 px
72 pt / 72 * 150 = 150 px
这个故事的寓意是,dp
保持精确的尺寸并有助于保持性能,允许根据设备密度进行一些物理尺寸变化。另一方面,pt
每个密度的物理尺寸完全相同,这会导致使用量不同px
,如果在图像上使用,这可能会影响性能并导致锯齿和伪影。dp
除非需要绝对精确的物理尺寸(屏幕上有尺子等),否则建议使用。
我写了一篇关于 Android 维度单位的深入博客,其中提供了更多信息和示例代码 -了解 Android 中的密度独立性
出于好奇,我在我的两台设备上尝试了约翰回答的布局:华硕 Transformer(10.1 英寸)和 HTC Legend(3.2 英寸)。结果非常有趣:
变压器(裁剪):
和传说:
我一直在与维度作斗争,但我认为我找到了一种对我来说有意义的看待它的方式。Wei-Meng Lee 的“开始 Android 4 应用程序开发”(第 111 页)中有一个转换公式:
实际像素 = dp * (dpi / 160),其中 dpi 为 120、160、240 或 320
因此,使用该公式,我可以找到我的手机/模拟器的哪个 dpi 最接近这四个值之一,这将确定公式中用于转换的比率(3/4、1、3/2 或 2) dp 到像素。对我来说重要的是,公式中的 dpi 只能假设这四个值之一,尽管实际设备像素密度。
参考:http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density,对于像素密度为 235 dpi 的 Nexus S,转换为:
像素 = dp * 3/2
所以一个 160dp 的按钮,比如说,将是 240px(比设备的 235 dpi 的一英寸宽一点)
对于 HTC Legend,像素密度为 181 dpi,公式为:
像素 = dp * 1
(因为 181 最接近 160)。因此,160dp 按钮将是 160 像素,或者在像素密度为 181dpi 的设备上略小于一英寸。
这有助于我理解之前的 Android 文档“1 dp 将始终等于 1/160in,无论屏幕密度如何”的错误。
这是我试图在脑海中理解的两个要点:)
- 一系列实际设备像素密度(例如:141-199)将在转换公式中产生相同的比率 (1)
- 但除非特定设备的像素密度正好是 160 dpi,否则 160 dp 在设备上不会是一英寸...接近上方或下方,但不完全是
pt 点 - 基于屏幕物理尺寸的 1/72 英寸。
dp Density-independent Pixels - 一个基于屏幕物理密度的抽象单位。这些单位与 160 dpi 屏幕相关,因此 1 dp 是 160 dpi 屏幕上的一个像素。dp与像素的比例会随着屏幕密度而变化,但不一定成正比。注意:编译器同时接受“dip”和“dp”,尽管“dp”与“sp”更一致。
如果可以使用 pt,为什么还要使用 dp?
开发人员习惯于用像素来思考事物。与密度无关的像素是 Android 接近开发人员习惯的方式。话虽如此,如果您愿意,欢迎您使用点、英寸或毫米。
无论屏幕密度如何,1 dp 始终等于 1/160 英寸。
如您的应用程序所示,这不是真的......同意吗?
BR 斯坦