天天看点

android多屏幕适配(1)

基于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为单位指定了高度和宽度,那么为什么会出现下图的情况呢?

android多屏幕适配(1)

在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

 and

ydpi

, 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硬件厂商令人眼花缭乱的屏幕尺寸种类,做到这一步,已经很不易了)。

继续阅读