ps:19 年第一篇,新年开头新气象,祝愿大家新的一年有好心情,好工作,事业顺利,感情稳健,身体健康,大吉大利~
之前写过一篇关于屏幕适配的文章,当时觉得资料看的很齐全了,但是吧,去年 10月份开始,屏幕适配又火了起来,原因是头条公布了自己的适配方案,随后在各大微信公众号,简书首推上都能看到屏幕适配的身影,还都是一些资深人事的文章,不得不去重视,不去重新研读
上一篇屏幕适配文章:
适配思路归纳
从现在的角度看,屏幕适配现今有 3 个思路:
- smallestWidth 最小宽度值适配思路,这是基于系统原生资源选择适配逻辑的
- 修改 displayMetrics 显示矩阵
- 修改 displayMetrics.density 或是 densityDpi,代表就是今日头条,强行修改目标设备的 densityDpi = UI 设计稿的 densityDpi
- 使用 pt 单位,借助 displayMetrics.xdpi 这个参数,、在系单位转换公式中注入我们想要的公式,实现百分比转换
市面上基本上就是这 3 种了,其他我是没看到过了,下面我大概各自说一下,我会把高玩们的相关文章贴出来,大家再去仔细研读,核心代码都很少,主要是大家看思路,未来换了平台估计思路还是如此
smallestWidth 适配
根据大家的反应,smallestWidth 的思路应该是用的人最多的,因为 smallestWidth 核心是用脚本生成相应的 values - smallestWidth 文件夹下的 dimens 文件
优点:
- 不涉及到代码,使用起来也是很简单
- 兼容性最好,没有麻烦的某些设备不适配问题
缺点:
- 稍稍有些误差,values - smallestWidth 不可能适配我们所有的设备,smallestWidth 原生适配思路是向下寻找,比如 设备:smallestWidth - 320dp,我们只有 smallestWidth - 300dp,那么就是使用 smallestWidth - 300dp 里面的 dp 值,多少实际是有差距的,一般 UI 都不是很严格,这没多打事,可以接受的,我用 smallestWidth 2年了,实际走下来,感觉适配效果还是不错的
- values 文件夹需要脚本自动生成,这里就需要有相关脚本功底了
- 一般只能以宽度为基准
关于生成 smallestWidth 的相关插件,方法看下面:
-
一种非常好用的Android屏幕适配
作者自己实现了一个自动生成 values 的 as 插件,韩简单,很好用,非常推荐 -
Android 目前稳定高效的UI适配方案
拉丁吴大神也发文提供了自动生成 values 的 java 脚本,不过不是 as 插件 -
给你一个全自动的屏幕适配方案(基于SW方案)!—— 解放你和UI的双手
我看了文章, 没看他的代码
另外介绍 smallestWidth 的文章:
修改 displayMetrics 显示矩阵
这个就得说今日头条了,头条就是这个思路,我的 UI 稿子设备 densityDpi 是 360dpi 的,那么我让适配设备的 densityDpi 也是 360dpi 就好了
densityDpi 计算公式 = 屏幕对角线的 px 值 / 屏幕物理尺寸
density 屏幕密度 = densityDpi / 160dp ,densityDpi 原始计算方式我们做不得手脚,我们用 density 代替 densityDpi 去做手脚欺骗系统
这里具体有2种写法:
- 根据前后设备 density 比例去,修改 densityDpi
resources.displayMetrics.density = resources.displayMetrics.density * ( resources.displayMetrics.density / uiDensity)
resources.displayMetrics.densityDpi = resources.displayMetrics.densityDpi * ( resources.displayMetrics.densityDpi / uiDensityDpi)
先说明啊,这不是今日头条的思路,这是我看其他人的思路总结出来的,这个方案我们需要知道 UI 稿的分辨率和物理尺寸去计算 density 和 densityDpi ,然后我们自己把 view 宽高的 px 转成 dp 去标记
- 强行让适配设备的 densityDpi = UI 稿的 densityDpi
头条的方案最简单暴力,大家看下面这个公式,就是这个思路:
density = 设备真实宽(单位px) / 360(UI 稿的 densityDpi)
这样 density 就会跟着改,计算出来的 px 值就会匹配真实设备了
// UI稿 densityDpi = 360dpi
resources.displayMetrics.density = resources.displayMetrics.widthPixels / uiDensityDpi
resources.displayMetrics.densityDpi = uiDensityDpi
有网友进一步引申,360 dpi 是 UI 稿的 dpi ,那么我们要是用 UI 稿的宽 px 呢,那么我们在 xml 布局时还是用 dp 单位,但是数值就可以直接用 px 的值了,不用去自己把 px 计算成 dp 了,省事不少
好了我说的就是这么多了,头条的原文如下:
JessYan 的 AndroidAutoSize 兼容多种适配方案,介绍看第一篇,后面是 github 地址
需要注意的是 displayMetrics 有3个地方可以获取到
Resources.getSystem().displayMetrics
Activity.resources.displayMetrics
Application.resources.displayMetrics
api 26 8.0 以后 Activity.resources.displayMetrics 和 Application.resources.displayMetrics 获取的同一个类,但是 26 以下就不是一个类了。Resources.getSystem().displayMetrics 这个不能改,这个改了整个手机都跟着变
pt 适配
关于 pt 适配的文章和思路虽然比较小众,但是也有不少人在用,在介绍,下面是我们自己写的 pt 适配工具:
pt 思路根据我找到的资料,貌似都源于这个作者的这篇文章:
其他如下:
-
AndroidUtilCode
看作者的文章思路是说用 头条的思路在写的,最后我看下代码还是变到 pt 适配去了