再学Android之屏幕适配

1,075 阅读4分钟

屏幕适配

做安卓的都知道,Android是不推荐我们在布局中直接使用px的,而是使用dp,那么接下来我们就先了解一下几个概念: px:绝对像素 dp:设备独立像素,也叫密度无关像素 sp:独立比例像素 dpi:像素密度,假设每英寸有160个像素的话,那么这个屏幕的dpi就是160,也就是在系统软件上指定的单位尺寸的像素数量,它 往往是写在系统出厂配置文件中的一个固定的值 ppi:也是像素密度,只是这个是物理上的概念,他是客观存在的,不会改变。而dpi是参考了物理的像素密度之后,认为的指定的一个值。这样便可以保证在某一个区间的物理像素密度,在软件上使用同一个值,这个值就是dpi

我们先记住几个公式:

1英寸 = 2.54cm

density = dpi / 160

px = dp * density

px = dp(dpi/160)

在日常开发中我们使用dp,再加上百分比,或者权重等,只可以基本满足适配,要想还原设计稿,还是要做别的工作,那么下面我们就 介绍下日常开发中常用的方式:

宽高限定符

简单点将就是穷举市面上所有Android手机的宽高像素值 假设以320480为基稿的话,那么我们把宽分成320份,那么每一份就是1,高同理,那么x1 = 1,x2 = 2,y1 = 1,y2 = 2, 那么在10801290的手机上我们该怎么做,320/1 = 1080/?,那么 ?=3.375,那么此时的x1 = 3.375,x2 = 6.75,高也是这样计算,那么,我们将值对应的放在文件下面,即res/values-480320和res/values-19201080,

注意

1.这里的文件的名字是高*宽
2.这里使用的是px
3.一定要有一个默认的文件,即res/values,原因如下:
    使用该方式,是精确匹配,如果匹配不到的话,
    那么就会使用默认值,所以要给一个默认的文件,使用我们常用的dp

最小宽度适配

smallestWidth,也叫sw限定符适配,指的是Android会识别屏幕的最小尺寸的dp值,然后根据识别到的结果去资源文件中 寻找对应的限定符的文件。这种方式跟上面的方式其实是一样的,但是容错机制会比上面的好。 举个例子:如果手机的dpi是480,横向的像素是1080px,那么根据上面的公式:px = dp(dpi/160),那么此时的dp=360, 系统就会去寻找是否存在value-sw360dp的文件夹以及对应的资源文件,如果找不到value-sw360dp这个文件夹的话,会向下去找 最接近的文件夹,比如:value-sw350dp

注意:

这里计算时使用的是最小宽度,跟手机的高的像素值没有关系
文件夹的命名不能出错:使用value-sw360dp
这是使用的是dp

smallestWidth的适配机制由系统保证,我们只需要针对这套规则生成对应的资源文件即可,不会出现什么难以解决的问题,也根本不会影响我们的业务逻辑代码,而且只要我们生成的资源文件分布合理,,即使对应的smallestWidth值没有找到完全对应的资源文件,它也能向下兼容,寻找最接近的资源文件

今日头条适配方案

mp.weixin.qq.com/s/d9QCoBP6k…

原理:利用公式:px = dp * density,假设设计稿的宽度是360px,那么我们就会目标的值设置为360dp,通过修改像素密度density的值 从而来保证这个值始终是360即可,这样的话就能保证UI在不同的设备上表现一致了.

参考blankj大佬的文章: www.youtube.com/watch?v=ckZ…

缺点:由于头条的方案是直接修改 DisplayMetrics#density 的 dp 适配,这样会导致系统 View 尺寸和原先不一致,比如 Dialog、Toast、 尺寸,同样,三方 View 的大小也会和原先效果不一致。 有时会存在DisplayMetrics#density 被还原的情况,需要自己重新设置回去,最显著的就是界面中存在 WebView 的话会被还原

可以参考下面blankj大佬的使用pt作为适配单位的文章: blankj.com/2018/12/18/…