Android中基于dp的UI布局
Updated:
分辨率布局的局限
Android设备分辨率千奇百怪,基于pixcel的布局无法在不同的分辨率有一致的显示效果,如下图所示,要让一个button在320*240和640*480的两种分辨率下有一致的布局,设置相同的pixcel行不通。
为减少开发人员的适配工作量,Android引入了dp的概念,在xml布局文件中可以直接设置单位为dp的值,要了解dp,先要了解下面几个概念。
布局表示单位
分辨率
Android设备输出分辨率
Android设备输出分辨率和连接Android设备的显示器尺寸是没有关系的,很多博客上面用手机的尺寸和分辨率来计算dip是不准确的,Android设备输出分辨率只表明android设备的显示输出能力,如果一个Android设备输出分辨率为640*480,每英寸像素数为320,那么连接这个android设备的显示器最佳尺寸为:
(640/320) * (480/320) = 2英寸 * 1.5英寸 |
本文后面的分辨率,主要是指Android设备输出分辨率
显示器分辨率
每个显示器有自己支持的显示分辨率,如果输出分辨率小于显示分辨率,那么通过居中或者插值填充的方法来显示, 如果显示器分辨率大于输出分辨率,显示器模块负责压缩显示或者只显示输出画面的局部
dpi
dpi:每英寸像素数,Android设备上dpi的主要值是120 dpi、160 dpi、240 dpi、320 dp
density
density:像素显示密度,基于dpi的一个衍生概念,是dpi归一化的值,跟dpi成正比,计算方法为:
density = dip / 160 |
目前Android设备上density主要值为0.75、1、1.5、2、3,Android中可以用代码来获取:
float density = getContext().getResources().getDisplayMetrics().density; |
dp
dp也叫dip,dip是Density independent pixel的缩写,它的计算就是基于分辨率和density的,如果一个分辨率为640*480的Android设备,density为2,那么屏幕的dp为:
(640/2) * (480/2) = 320dp * 240dp |
代码中可以根据分辨率和density来计算dp,这样,如果两个设备之间分辨率不一样,只要分辨率和density的比例是一样的,就可以统一表示
比如另一个分辨率为320*240的Android设备,如果它的density为1,那么它屏幕的dp为:
(320/1) * (240/1) = 320dp * 240dp |
这样两个Android设备对屏幕都有同样的表达方式:
dp也无能为力
不同设备之间只有用拥有统一的dp大小才能共享同一个布局方案,如果dp不一样的情况,那么就需要针对不同的dp进行处理了,android下面有一个values目录,里面通过dimens.xml来设置布局的dp
values-w540dp-hdpi |
格式如上所示w540dp代表宽度为540dp,hdpi代表density为1,针对不同的dp,需要新建对应的目录,App会在运行时根据设备情况加载对应的目录里面的dp值
建议
如果可以不用数字来布局的尽量不要用,可以用百分比来代替:开源库
不同的手机里面dp之间差距不大,布局之间的差异不明显,但是现在的智能电视和手机之间dp差距大,需要做好适配