从事android开发已有5年之久,项目中遇到的屏幕适配的问题也有n次了,可是有一个很奇怪也很让人头疼的现象让从事多年开发的我很不爽。什么问题呢,就是“适配虐我千万遍,我见适配如初见”,真是想说一句fuck,这次我终于坚决的征服掉了她,下面就来具体讲解征服她的全过程,一定要有决心,耐着性子慢慢看。
本着不重复造轮子的理念,对现有适配方案统统拿来细细研读了一番,得出的结论是已基本可以解决适配问题,但是如果你去百度可以发现有不止一种解决方案,这些方案哪一个更好呢,听我来慢慢分析。(客官莫急,要知道心急吃不到“热豆腐”)。
首先,为了节约用纸,涉及到的一些基础知识就不在这里赘述了,留下传送门方便小白穿越:
android UI设计图片和文字尺寸px对应dp、sp值换算
Android 屏幕适配:最全面的解决方案
下面是现有各种方案总结比较好的文章:
为了方便阅读本文,还是啰嗦补充几个基础要点,以免“仁者见仁”:
从上面dp的公式可以看出官方提供的dp单位只是像素无关 但是和尺寸很有关,所以dp无法适配差别较大的尺寸屏幕,这也就是屏幕适配问题的由来。
首先要普及一个概念叫“最小宽度限定符”,系统可以识别这些限定符来匹配相对应的屏幕尺寸所需要的资源文件,最常用的例子就是mipmap-xdpi作为图片资源的限定,那其实所有res的资源都有对应的限定符,比如layout布局文件有layout-large限定符来匹配大屏,values也有类似的限定符供app运行时选取。
方案一:px适配法原理
以某一分辨率(比如480*320)的 宽度 为基准,其他分辨率按宽度等比例缩放(高度由于习惯滑动,所以采用宽度为基准),在values文件的dimens文件中定义x1=1px…x320=320px。如果UI设计师是在宽度为640px的屏幕上做的标注,那么1px在xml中引用资源变量为x0.5,也就是要用小数来表示了,所以采用较大宽度的分辨率作为基准比较合适,推荐使用1080作为基准。
基准值选好后以此生成其他各分辨率对应的资源文件,理论上是生成的文件越多适配误差越小,但是受限于安装包大小一般选取主流分辨率适配。
方案二:dp适配法原理
这种方案原理和px适配法是一样的,只是“最小宽度限定符”的单位不同罢了。用dp作为限定符的好处是可以减少适配资源文件的数量。这里有一个容易误解的点dp作为限定符来区分不同宽度的屏幕,在计算比例时容易理解为dp总值的比例,例如360dp和480dp的换算比例易误解为480/360=1.5,其实不是这样子的。比例的结果还是要将宽度换算为px的出。具体dp到px转换可以参考上文传送门的基础篇,比较详细。
方案三:百分比适配法原理
这个方案也是和px适配法同样的原理,百分比顾名思义只需要在px基础上除以总宽度即可。而且现在也不需要再去手写了,官方已经给出兼容包提供百分比布局:PercentRelativeLayout、PercentFrameLayout,线性布局的百分比布局没有给出可在参考链接中鸿神的文章里查看到亲手仿制的。
方案四:单位转换法原理
此种方案的原理比较简单粗暴,系统进行长度计算的接口为TypedValue中的applyDimension函数,传入单位与value将其计算为对应的px数值:
public static float applyDimension(int unit, float value,DisplayMetrics metrics){
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
方案一
方案二
方案三
方案四
以上四种方案在布局预览时都需要使用和UI设计同样的尺寸。
综合以上分析方案二相较方案一适配性更好优先选择,方案三在简单布局上优势较为明显,方案四不稳定因素较多。
最后,感谢看到这里的同学,有哪里觉得不理解或者感觉不对的地方欢迎评论留言,会尽快回复。