基于android官方doc,力图以较为简洁的方式说明android多屏幕适配的相关技术。
屏幕尺寸(Screen size)
屏幕对角线的物理尺寸。android将所有屏幕尺寸分为四类:small、normal、large和extra large
屏幕密度(Screen density)
单位(屏幕)物理区域中像素的数量,通常使用dpi(dots per inch),即每英寸像素数来表达。
比如,单位区域内,低密度屏幕所含的像素数比高密度屏幕所含的像素数少。
android将屏幕密度分为四类:low、medium、high和extra high
方向(Orientation)
屏幕的方向,分为landscape和portrait两种。
分辨率(Resolution)
屏幕中物理像素总数。要支持多屏幕时,应用程序不直接与分辨率打交道,只需关心屏幕尺寸和屏幕密度。
密度独立像素(Density-independent pixel,简写为dp)
dp是一个虚拟的像素单位,当定义UI布局时,应该使用dp,以屏幕密度无关的方式来定义布局。
一个dp等于160dpi屏幕上的一个像素。在运行时,基于屏幕密度,系统自动对dp描述的尺寸进行缩放。
dp与px的换算关系:px = dp*(dpi/160)。例如,在240dpi的屏幕上,1dp=1.5px
----------------------------------------
屏幕密度的计算公式 = ((分辨率长^2 + 分辨率宽^2)^(1/2))/屏幕尺寸
也就是根据分辨率的长宽计算出对角线的像素数(利用勾股定理),再用对角线像素数除以对角线长度(即屏幕尺寸)
可以参考android应用 DPI Calculator
下面以几个真实机器来加深一下相关概念的认知
三星i5801 | HTC wildfire S(g13) | HTC sensation(g14) | meizu m9 | |
---|---|---|---|---|
分辨率 | 240*400 | 320*480 | 540*960 | 640*960 |
屏幕尺寸 | 3.2英寸 | 3.2英寸 | 4.3英寸 | 3.5英寸 |
屏幕密度 | 145.77 | 180.27 | 256.15 | 329.65 |
DisplayMetrics得出的DPI | 120 | 160 | 240 | 320 |
黄色部分为使用上述公式计算的屏幕密度,绿色部分为使用DisplayMetrics得出的dpi,可以看到比较接近
有两方面的原因,导致这两个数据不一致
1.厂商给出的屏幕尺寸参数不是太精确
2.DisplayMetrics中定义的密度值只有120、160、213、240、320
----------------------------------------
这里从另一个角度可以进行屏幕尺寸的反推,以meizu m9为例,通过DisplayMetrics可以得到其xdpi和ydpi均为325.12
这样屏幕宽度=640/325.12=1.9685英寸,屏幕高度=960/325.12=2.9527英寸
使用勾股定理计算得出,对角线尺寸为3.5487英寸
这里有一点存疑,HTC wildfire s(g13)的xdpi=159.37254,ydpi=160.42105,通过上述方式推算出其屏幕尺寸为3.6英寸,与实际手机的屏幕尺寸不符。其他机型则没有出现计算结果与实际尺寸不符的现象!?
----------------------------------------
好,既然dp是android推荐在布局时使用的单位,并且在布局中以dp为单位指定了高度和宽度,那么为什么会出现下图的情况呢?
在http://developer.android.com/reference/android/util/DisplayMetrics.html中,描述density时有这样一段话
The logical density of the display. This is a scaling factor for the Density Independent Pixel unit, where one DIP is one pixel on an approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), providing the baseline of the system's display. Thus on a 160dpi screen this density value will be 1; on a 120 dpi screen it would be .75; etc.
This value does not exactly follow the real screen size (as given by xdpi
andydpi
, but rather is used to scale the size of the overall UI in steps based on gross changes in the display dpi.For example, a 240x320 screen will have a density of 1 even if its width is 1.8", 1.3", etc.
也就是说,在240*320分辨率的屏幕上,1.5"x2"、1.8"x2"和1.3"x2"这三种屏幕的density都是1。屏幕尺寸不同,像素数相同,那么像素的大小必然不同,如果指定一个固定的dp值,那么其对应的高宽值必然不同了。但是android能够最大限度的保证,使用dp为单位的布局,其差距不会太大(对android硬件厂商令人眼花缭乱的屏幕尺寸种类,做到这一步,已经很不易了)。