Android屏幕适配笔记

背景介绍

因从事Rom相关工作的原因,绝大多是时候都是在Android源码的基础上进行二次开发,往往一个分支也只需要适配一个机型,很少认真考虑过多分辨率适配问题。最近公司要做一个 APP,这次产品形态不一,大小不一,需要考虑多分辨率的适配了。为此在网上看了一些文章,大多都是在讲 dpi 和分辨率的事,写的也挺好的,这里根据自己的实际情况做一下整理记录。

已有方案

举个栗子:
设计稿是1280*800,px单位的,按已有方案来操作,需要以1280*800,160dpi为基准使用dp等像素密度单位(此时 1dp = 1px),其它分辨率则根据 dpi 和屏幕尺寸进行缩放即可。

dp 转 px 规则:
1dp = (屏幕密度 / 标准密度) * 1px,标准密度是160dpi。
这就是说,在设备密度是160dpi时,1dp = (160dpi / 160dpi) * 1px = 1px

比如设计图上一个 image 是300px*300px,那用1280*800,160dpi,7寸的样机布局用300dp*300dp就可以了,如下图

然后800*480,160dpi,4寸的机器,就可以换算为300dp / 7 * 4 = 171dp,效果如下:

可以看到,经过换算后,两种同dpi,不同分辨率的显示效果基本一致。

PS:此处的比例换算比较粗糙,没有考虑实际宽高带来的变化,仅供参考。

如果还需要其它分辨率,也只需要再加一套相应的demin即可。最后你的values资源可能就是这个样子的:

values
values-1280x800
values-800x480

总的来说这样操作下来,可以说大部分设备都是OK的,而且也是目前比较主流的适配方案。但个人觉得有个前提条件——设备分辨率与dpi是固定不变的

dpi 引发的问题

前面的已知方案,可以覆盖大部分设备,但有前提条件,就是设备的分辨率和dpi是不会变的。

Android N以前,dpi是固定的,由 build.prop 属性ro.sf.lcd_density决定,用户使用过程中,这个值是不会改变的。

但自从Android N开始,在Settings > Display 中多了一项设置——“Display size”,如下图所示:

默认情况下,这里选中的值和ro.sf.lcd_density是对应的,但用户可以手动修改这里的值,进而引起dpi变化。当 display size 设置为 largest 时,原本表现正常的800*480,160dpi,4寸的机器就是这样的:

可以看到这个image的占用的屏幕空间已经变化了很多,不再是之前的娇小模样了。

为了应对这个改变,我们又得修改values资源,给某一个分辨率添加多套 dpi 了。这时你的values资源将会变成这个样子:

values
values-136dpi-1280x800
values-160dpi-1280x800
values-186dpi-1280x800
values-212dpi-1280x800
values-240dpi-1280x800
values-320dpi-1280x800
...
values-136dpi-800x480
values-160dpi-800x480
values-186dpi-800x480
values-212dpi-800x480
values-240dpi-800x480
values-320dpi-800x480
...

看到要写这么多目录,每个都要换算一遍,是不是躲在角落里瑟瑟发抖?
淡定这才两个分别率呢,分辨率再多点就是这样了:
此图来源于网络
是不是顿时有种要锤人的冲动?
别鸡冻,网上有大佬写好的工具,可以自动生成这些目录,自己去问问度娘吧。

那么,display size 和 dpi 又有什么关系呢?自己看吧:

要注意的事,表格中红色字体标注的值,在不同 dpi 下会不同,而且和实际屏幕分辨率存在差异,这部分差异就是虚拟按键占用的大小。
也就是说,800*480的屏幕,APP能获取到的width并没有800;而且即便APP申请全屏显示,也拿不到800。因此,800*480的机器,并不会引用values-800x480的资源。(反正我手上这两台机器都不买账)

px 代替 dp

前面说了,现在的Android设备,一个屏幕可以有多个 dpi,如果按照已有的方案来适配,那就存在分辨率、dpi两个变量,demin的数目就是 分辨率个数 * dpi个数,这样以来在一定程度上就会增大APP体积,维护上也会带来不便。因此这里本人采用了一种偷懒的方法——用 px 代替 dp 进行布局

首先要知道一个屏幕,一般情况下分辨率是不会改变的(二般情况下会变,比如华为荣耀的屏幕省电功能),因此我们可以使用 px 布局,这样就只需要关注分辨率大小,不需要再关注 dpi 了,此时要适配那些分辨率就只需要根据基准分辨率的 px 值进行缩放即可。

这样一来,1280*800的分辨率一套demin就够了,随你怎么调节dpi,反正分辨率是不会动的。适配800*480时,也只需要再多加一套demin即可,完全不必再考虑用户手动改 dpi 的问题了。

在加上前面说的,APP拿不到实际的分辨率大小,因此最后我的目录就是这样的:

values
values-1200x720
values-720x480

小结

最后,dp、sp毕竟还是官方推荐的,总是有它的原因的,还是建议优先考虑使用dp、sp布局。使用px布局纯属本人偷懒,仅作一种参考方案。

猜你喜欢

转载自blog.csdn.net/ShawnXiaFei/article/details/81142780