Dpi dp and px

这几天折腾了一下 android 上面的布局,了解了一些基础概念。

首先有两个概念,一个是分辨率,一个是屏幕的实际尺寸。我们一般讲的 800x600 像素(px),1024x768 像素(px)这些,都是分辨率。然后 5.5 寸(iPhone 6/7/8 plus),4.7 寸(iPhone 6/7/8),10.1 寸(iPad) 这些是实际尺寸,并且指的是屏幕对角线尺寸。

一般来讲,除非是 5.5 和 10.1 这么大的差异,我们大多会在比如 5.5 和 4.7 上面使用同一个设计。比如在最上面 1cm (为什么说物理距离呢,因为手机屏幕就那么大,你不能把内容显示的太小,否则会看不清楚) 显示一个黄色的提示条。那么接下来的问题就是,1cm 对应的像素,就算在同一个设备的不同的分辨率下面,都是不一样的。那图怎么做?

如果 20px 的图放到 800x600 的分辨率下面刚好,那么这个图放到了 1600x1200 的分辨率下面(这里说的是屏幕物理尺寸不变的情况下,因为如果物理尺寸如果也变大了,那就是另外一个情况了),不做缩放的话,就是会得到比 800x600 小一倍的效果。如果缩放的话,那就大小一样了,但是可能因为缩放导致失真。实际做法就是针对不同分辨率做不同的尺寸的图。比如针对 800x600 分辨率,做一个 20px 的图,那对于 1600x1200 分辨率的,做一个 40px 的图。以此类推。

这样,三个概念就出来了

  • density 也就是 dpi,屏幕密度。
  • dp 是一个长度单位。
  • 常见的 1x, 2x, @2x 这些。

density(dpi,屏幕密度) = 屏幕对角线的像素/对角线的物理尺寸 = (屏幕长的像素的平方 + 屏幕宽的像素的平方)开根号/对角线的物理尺寸,比如 iphone 3G/3GS 是 160, iphone 4 是 320。

dp = px x 160 / dpi。比如 160dp 在 160 dpi 下面是 160px,在 320 dpi 下面是 320px。其实就是说,160dp 我们在 iphone 3g 上和在 iphone 4 上看到的物理长度是一样的。

1x, 2xpx/dp = dpi/160。从上面那个例子也能看到,这个其实就是指 px 和 dp 的换算关系。一般我们要在某个手机上面开发,主要弄清楚的就是这个倍率就可以了。在 1x 的设备上面,想要展示 10px 的图,那么给 2x 的设备就得切一个 20px 的图,才能达到和 1x 上面一样的视觉效果。

那我们一个 app 是需要同时准备展示在很多类型的设备上面的,1x, 1.5x, 2x 3x 等,总不能靠程序去计算然后决定用什么图吧。各系统其实已经做好了简单的适配方法了。比如 ios 里面,是通过给图取不同的名字来解决的,例如 [email protected][email protected],ios 系统会自动去用对应的图。而 android 系统里面,是通过把图放入不同的目录来解决的,例如 drawable,drawable-hdpi, drawable-xhdbi,这几个分别对应 1x, 1.5x, 2x。

其中要注意的是不要放错目录。如果把一个 1.5x 的图,放到了 1x 的目录下面,然后展示在一个 1.5x 的设备下面,会发现图会被缩放到 1.5 倍大小。

参考链接: