为了查看方便,特意贴一段 Google API 文档:http://developer.Android.com/intl/zh-cn/guide/practices/screens_support.html
近期做些关于手机适配的工作。
下面来总结一下,希望可以对大家有帮助,本人能力有限,如果有解释失误的地方,请务必帮忙指出,谢谢。
首先引入几个概念。
PPI : Pixels Per Inch的缩写简称,表示的是每英寸显示屏所拥有的像素(pixel)数目。
DPI : Dots Per Inch , 最初用于衡量打印物上每英寸的点数密度,就是说你的打印机可以在一英寸内打多少个点。
DPI用来表示输出设备的输出精度,如打印机,显示器
DPI表示的是 像点/英寸(每英寸长度上有多少个打印点或像点)
PPI用来表示输入设备的输入精度,如扫描仪,数码相机
PPI表示的是 像素/英寸(每英寸长度上有多少个像素)
显然,在谈到Android设备屏幕时,用DPI 比较合适,官方文档中也是用DPI来说明的。当然,如果有人说成PPI,也并不妨碍理解,只是这种说法不太准确。
关于如何计算DPI ,下面我们拿三星S3为例。
根据三星官网给的 信息:
The S III's HD Super AMOLED display measures 4.8 inches (120 mm) on the diagonal. With a 720×1280-pixel (720p) resolution, its pixel per inch (PPI, a measure of pixel density) is a relatively high 306。
我们可知:分辨率为 720x1280(高宽比为16:9) , 4.8英寸 , 306dpi。
那么,这个dpi是如何计算出来的呢?
由于对角线长为4.8英寸,我们要计算对角线上一共有多少像素点。
勾股定理可知:斜对角线的像素点 =
进而求每英寸的像素点个数,即 (在Android中,大家把PPI 和 DPI 看成一个东西即可)
这么计算后可知,三星S3的DPI = 306. 即,该手机每英寸有306个像素点。
下面再介绍Android中非常重要的几个概念。
dp (或 dip) , Density-Independent Pixels. 按照字面意思:密度无关的像素点。
那么,何为Density?
先了解一下屏幕的级别:
屏幕级别
屏幕密度DPI
密度比值
像素量/英寸
通常的分辨率
ldpi
120
0.75
120
240x400
mdpi
160
1
160
320x480
hdpi
240
1.5
240
480x800
xhdpi
320
2
320
xxhdpi
480
3
480
在这里,Android将mdpi 下 px:dp = 1:1换算。将其设置为baseline后,它的density为1.其他手机的density就能轻易算出来。
(可能有人会问为何dp是这么定义的?因为,Android历史第一部手机:T-mobile G1 就是这种分辨率)
(出自HTC,2010年停产,里程碑产品)
如果不是以上给出的这些通常的分辨率,那么我们如何确定它的DPI呢?
比如手机基伍A800 ,5.0英寸 , 分辨率为540x960 , 根据公式计算得出 DPI = 220,
那么,就近原则,它的屏幕密度被认为是240dpi , density = 1.5 , 找的相关资源图片在 drawable/hdpi 文件夹下。
如果想利用sw
Step1: 可以通过adb命令来快速获取手机的屏幕参数: adb shell dumpsys window displays (this command can get all display information, include resolution and dpi.) 通过该命令,我们可以取得手机的dpi(dot per inch),以及分辨率等。 Step2: dp和px的换算公式: dp = (px * 160)/ dpi
注:这里的dpi是归化后的dpi,并非是真实的dpi。基伍A800的真实dpi为220dpi,归化后的dpi只有这几种:
A set of six generalized densities:
ldpi (low) ~120dpimdpi (medium) ~160dpihdpi (high) ~240dpixhdpi (extra-high) ~320dpixxhdpi (extra-extra-high) ~480dpixxxhdpi (extra-extra-extra-high) ~640dpi
Android会取就近的dpi值,220离240最近,所以基伍A800的机器dpi为240.
拿A800 为例,屏幕分辨率为 960*540 ,dpi 为 240。 因为我们要计算sw
2015-06-25 再次补充:
在机型适配的时候,还会碰到更加棘手的问题。 比如: 三星S2的分辨率:480*800 小黄蜂hyf9300的分辨率:480*854 此时,小黄蜂的分辨率在竖直方向的高度比S2多了54像素点高度,而上述的sw
谷歌在3.2以后推荐使用以下这几种方法来进行适配:
Table 2. New configuration qualifiers for screen size (introduced in Android 3.2).
其中,h
机型
分辨率
全屏高度h
三星S2
480*800
N = 800*160/240 = 533.33dp
小黄蜂
480*854
N = 854*160/240 = 569.33dp
A800
540*960
N = 800*160/240 = 640dp
由于我们团队开发的应用只有状态栏是属于systemUI,所以该N还得减去状态栏的高度为25dp。
机型
分辨率
可用高度h
三星S2
480*800
N = 533.33 - 25 = 508.33dp
小黄蜂
480*854
N = 569.33 - 25 = 544.33dp
A800
540*960
N = 640 - 25 = 615 dp
该h
比如小黄蜂手机打开的应用检测出其可用高度为544.33dp,
先查找对应的文件夹即:values-h544.33dp/dimen.xml,如果没有找到,那么向下匹配。
实在找不到,最后才去values/dimen.xml中默认匹配。
所以,最后在保证可以查找到并且允许状态栏等高度小幅度变化的情况下,我们在代码中设定其高度为:
机型
分辨率
h
对应的适配文件
三星S2
480*800
N = 500dp
values-h500dp/dimen.xml
小黄蜂
480*854
N = 540dp
values-h540dp/dimen.xml
A800
540*960
N = 610dp
values-h610dp/dimen.xml
当然,最后还是别忘了在values/dimen.xml文件中加入默认的配置,以防在找不到的情况下发生crush。