android设备运行在各种不同的屏幕中,这些屏幕有着不同的screen sizes(屏幕大小)和screen densities(屏幕密度)。screen sizes表示屏幕的实际物理大小,比如5寸手机,7寸平板,8寸平板。而screen densities表示屏幕的像素密度,比如同样5寸的手机,有720p的,有1080p的。screen sizes和screen densities从两个维度表示了屏幕的属性,他们互不影响。
Screen Sizes
屏幕的真实物理尺寸,以屏幕的对角线测量,一般以inch(寸)为单位,比如5寸手机,7寸平板。如下图所示:
根据不同的屏幕大小,可以把屏幕大小分为下面几种类型:
- small
- normal
- large
- xlarge
这种分类方式是以第一部android手机G1为基准划分的,G1属于normal分类。随着android手机屏幕的尺寸大小越来越丰富,这种分类方式就显得简单粗暴,无法满足分类的精确度(比如5寸手机和7寸平板同属于large分类)。所以在android3.2以后就没有使用这种分类方式了,新的分类方式通过可用屏幕宽度来定义,在工程的资源文件中(如layout)使用,下面是一些例子:
- layout-sw600dp
- layout-sw720dp
- values-sw340dp
这些分类的定义在后面会详细讲解,现在大家先有个概念。
Screen Densities
在讲screen densities前有几个概念需要理解:px,ppi,dpi,resolution。
1. px
px就是大家经常说的像素(pixel),像素是图像显示的基本单位,pixel由picture和element两个单词组合而成,有图像元素的意思,每个这样的信息元素是一个抽象的采样,经常以一个点或者方块表示。
2. ppi
ppi(pixels per inch)表示图像中每英寸的像素数,ppi会影响屏幕输出的质量,高的ppi在每英寸下包含的像素数多,显示效果更好。对于一张100 x 100像素的图片,100ppi的输出显示的大小为1" x 1"(1"表示1寸),在10ppi的输出显示的大小为10" x 10"。也就是说,同一张图片在不同ppi下显示的大小不一样,ppi越大,图片显得越小。
3. dpi
dpi(dots per inch)跟ppi是比较容易混淆的两个概念,dpi表示屏幕每英寸物理显示点的个数,物理显示点是屏幕的最小显示单元。假如图像输出与屏幕的显示点一一对应,即一个pixel在一个dot上显示,那么dpi的值等于ppi。但如果用一个1200dpi的屏幕全屏输出一个300ppi的图像,那这时每个pixel由16个dots组成。(dpi与ppi的关系)
4. resolution
resolution表示屏幕分辨率,以像素为单位表示,如屏幕分辨率为1920 x 1080,表示屏幕x,y方向分别可以显示1920和1080个像素点。分辨率在应用实现多屏适配的时候不起直接作用,多屏适配只与screen sizes和screen densities相关。
对以上的几个概念有了初步认识后,下面我们来看screen densities的分类,在android中,screen densities是根据dpi来进行分类的,如下:
- ldpi(low)~120dpi
- mdpi(medium)~160dpi
- hdpi(high)~240dpi
- xhdpi(extra high)~320dpi
- xxhdpi(extra extra high)~480dpi
- xxxhdpi (extra extra extra high)~640dpi
- ......
为了简单,android根据dpi的值对screen densities进行了分类,每种分类包含了一个区域的dpi值,如上图所示。这种分类方式也是以第一部android手机G1为基准划分的,G1的dpi为160dpi,属于mdpi的分类。
下面ppi的计算公式,ppi是pixels per inch的意思,设备的ppi用屏幕对角线中每inch的pixel数来表示,
比如nexus5手机,分辨率为1920 x 1080,屏幕大小为4.95寸,那么ppi的计算如下:
那屏幕的dpi如何计算了,如果是按照定义的话,公式跟ppi的计算公式是一样的,只需把像素数换成dot的数量,但是我们并不知道dot的数量是多少。不过,我们可以通过程序获取设备的dpi值,代码如下:
DisplayMetrics dm = getResources().getDisplayMetrics(); int dpi = dm.densityDpi;通过上面代码获得的dpi=480,也就是说dpi不等于ppi,如果一个pixel用一个dot显示,按道理是应该相等的,但为什么会不等呢?这个我也还没搞清楚。不管怎样,要获取屏幕的dpi,不能用计算ppi的公式去计算获得,要从代码中去获取。
总结:
android设备的屏幕的差异通过两个维度来划分,screen sizes 和 screen densities,为了简单,android对不同的 screen sizes 和 screen densities做了归类。它们两者互不影响,一个表示屏幕的真实物理大小,一个表示屏幕的像素密度,这两者的不同组合构成了各种各样的设备屏幕。在对android应用做多屏适配时,它们是主要考虑的因素。