dp 与 px

前些日子做了几个嵌入安卓的 webview,找安卓同事要素材的时候,总是跟我提 dpdp 的,作为前端工程狮,常年和 px 打交道,有时也会用 rem 和 em。dp 是个啥?

参考网址:https://developer.android.com/guide/practices/screens_support.html

名词解释

像素和分辨率可以用于形容【图像】或【屏幕】,如不做特别说明,这里均指屏幕,图像情况类似。

像素(px)

表示组成图像的最小单位。我们看到的图像都是由色点组成的,假如我们在屏幕上看到一个樱木花道,放大看会发现它其实是由很多个纯色色块拼成的,其中最小的色块就是一个像素。

如果这里一个方格代表一像素的话,那么樱木的嘴和鼻子就是一像素。
在我们一贯的认知里,既然作为单位,那么一像素一定是固定大小吧!但是,像素大小真的不是确定的!它究竟多大,取决于分辨率的大小。

分辨率

分辨率为 “屏幕每行的像素点数 每列的像素点数”。
我们经常会听到屏幕分辨率是 320
480 的,表示屏幕宽度上有 320 个像素点,高度上有 480 个像素点。

屏幕尺寸

屏幕尺寸 4.0 英寸是指对角线 (敲黑板) 的长度为 4.0 英寸。1 英寸 = 25.4 毫米。

dpi

dpi 是 Dots Per Inch 的缩写,顾名思义,指每英寸的像素个数。

如果我们的屏幕是 4.0 英寸,屏幕分辨率为 480 * 800,我们可以通过计算得到 dpi 的值。根据勾股定理,屏幕对角线的长度为 932.952 像素(101.6 毫米),那么每英寸有 932.952/4.0 = 233 个像素,工业切割屏会取整,即 dpi 为 240。

顺手算一下像素大小,每个像素有 101.6/932.952 = 0.109 毫米。

dp

终于说到主角儿了,dp是啥?dp 也写做 dip, 是 Density Independent Pixels(密度无关像素)的简写。简而言之,dp 是 Android 发明的长度单位,也称为密度无关像素。

你一定会想说这是什么鬼?

事实上,这种说法是最有助于理解的,因为 dp 本身是人们为了方便开发而人为定义出的单位。它甚至不是什么的缩写,只是为安卓开发而生的一个虚拟单位。

dp 的推算

为什么不用 px?

px(像素)是我们开发过程中使用最广泛的单位之一,但是在 dpi 不同的设备中,由于每个像素的大小不同,如果我们画一条像素值同为 10px 的直线,就会产生下面的情况:

如果使用 dp 单位呢?例如同样是 10dp 的直线,表现是这样的:

鹅妹子嘤!

dp 的推算过程

见识了 dp 的神奇,那么 dp 到底是怎样得来的单位呢?

首先先来说说安卓系统面临的碎片化问题。目前,下图中每一个矩形都代表着当前市场上的一种 Android 设备的尺寸。

面临爆炸式增长的屏幕大小,谷歌规定了一个屏幕密度作为标准(baseline),即 160 dpi

我们不如假设 A 手机恰好就是 160 dpi 的屏幕,B 手机的 dpi 就设为 dpi(B) 吧。在 A 手机上需要显示一条宽度为 X px 的直线,这个值在 B 手机上则为 Y。

那么,它们之间存在这样一种关系:

X / 160 = Y / dpi(B)

经整理可得:

X = Y * (160/dpi(B))

这里,X 的单位就是 dp。

dp 与 px 的转换

根据上述推算,我们知道,dp 与 px 之间的转换关系为:

1
px = dp * (dpi / 160)

例如,在 240 dpi 屏幕上,1 dp = 1.5px。
我们始终使用 dp 单位,以确保在不同密度的屏幕上正常显示。

dp 的意义

直观来讲,如果我们用绝对像素单位来定义一个图像,那么它很有可能在不同密度的屏幕上显示完全不同的大小,但 dp 单位则保证了在不同密度屏幕上“看起来”是一样的。