android支持的设备很多,屏幕大小各不一样,要用同一个APP在不同的设备上运行,就要让UI在这些设备上合理地显示,一般需要缩放字体大小和UI的宽高等,也可以在不同大小的屏幕上显示不同的布局。在做屏幕适配之前,需要了解一些专业词语。
专业词语
Pixel (像素)
In digital imaging, a pixel, pel,[1] dots, or picture element[2] is a physical point in a raster image, or the smallest addressable element in an all points addressable display device; so it is the smallest controllable element of a picture represented on the screen.
这是wiki的定义,大意是在数字图片中,一个像素是一幅光栅图片中的一个物理点,或者是所有点寻址显示设备上的最小可寻址单元。像素的单位一般是px。
Screen size(屏幕大小)
屏幕的物理大小,是指屏幕对角线的长度(一般用英寸表示,比如5.0inch,6.0inch)。android大致将屏幕划分为small,normal,large,extra-large几个级别:
Screen density(屏幕密度)
The quantity of pixels within a physical area of the screen; usually referred to as dpi (dots per inch).
屏幕一块物理区域内像素的数量(ppi),通常也指dpi(dots per inch)。android将屏幕密度大致划分为六个级别:
屏幕密度
衡 量 值
ldpi (low)
120dpi
mdpi (medium)
160dpi
hdpi (high)
240dpi
xhdpi (extra-high)
320dpi
xxhdpi (extra-extra-high)
480dpi
xxxhdpi (extra-extra-extra-high)
640dpi
Orientation(屏幕方向)
用户视角的屏幕方向,通常为横屏(landscape)和竖屏(portrait),需要注意的是屏幕方向在运行时可以发生变化。
Resolution(分辨率)
整个屏幕的物理像素数量,例如:720x1280,表示屏幕宽度上有720个像素,屏幕高度上有1280个像素。屏幕分辨率和屏幕密度的关系是
但通常来说,使用此公式计算出来的结果和代码中返回的结果不一致,据我猜测应该是厂商返回的dpi是有修改的,并不是实际的DPI,这点暂时没有验证。
Density-independent pixel(dp,设备独立像素密度)
用于定义UI布局的虚拟像素单位,dp定义的尺寸和屏幕密度无关,dp是一个物理尺寸(和inch类似),比如50dp在160dpi的设备和240dpi的设备上显示尺寸是一样的。它的基准值是屏幕密度为160dpi的像素,也就是说在160dpi的设备上,50dp和50px的长度一样,而在240dpi的设备上,50dp和75px的长度一样,换算公式如下:
px=dp*(dpi/160)
从上式可以推出:px/inch=dpi==>px=dp*px/(inch*160)==>dp=inch*160 也就是说,1dp的长度为1/160英寸。
屏幕适配方法(支持3.2及以上)
屏幕适配,首先要明确适配的目标,根据目标屏幕大小决定是否需要做不同的适配。主要的适配方法如下:
图片适配
跟据屏幕密度(dpi)不同,将不同的图片放到合适的目录,比如drawable-mdpi,drawable-hdpi等。
布局和字体适配
xml中尽量使用比例布局layout_weight、wrap_content或者match_parent,使用指定大小时一定要用dp为单位,并且全部定义到dimens文件中;
使用getResources().getDisplayMetrics()获得屏幕基本信息,计算出最小宽度的dp值,用来区分不同大小的屏幕,对每个不同的屏幕创建values-swdp目录,在这些目录中定义相关的dimens文件;
字体大小全部使用sp,并且全部定义到dimens文件中。
示例:
APP有两个设备需要适配:
A设备:
DisplayMetrics{density=2.0, width=720, height=1280, scaledDensity=2.0, xdpi=320.0, ydpi=320.0}
B设备:
DisplayMetrics{density=1.5, width=720, height=1280, scaledDensity=1.5, xdpi=160.421, ydpi=160.157}
处理图片资源:
上面可以看出A设备对应的图片目录为drawable-xhdpi,而B设备对应的图片目录为drawable-mdpi,图片的大小比例是2:1,先把处理好的图片资源放到各自的目录。
计算它们的dp大小:
A设备的大小为: 720/2.0x1280/2.0=360dpx640dp,sw为360dp
B设备大小为:720/1.5x1280/1.5=480dpx853dp,sw为480dp
显然B设备要大一些,所以,我们可以将A设备的dimens文件放置到默认目录,然后创建values-sw480dp目录来保存B设备的dimens文件。对于dimens中的值,我们可以按等比缩放来设置,比如A设备中16sp大小的字,在B设备中等比缩放后应该是16*480/360=21.3约为22sp。
注意:swdp的方式,仅支持3.2及以上设备,在以前的设备上可以用分辨率和屏幕大小来设置dimens目录。