写点什么

Android 屏幕适配前先了解这些,在阿里工作 5 年了

用户头像
Android架构
关注
发布于: 刚刚

超大屏幕至少为 960dp x 720dp


为了简化屏幕适配,一般机型的 dpi 的取值会参考上面的范围,但是总会有一些特殊的机型就是不采纳官方的建议。如小米 MIX 2 分辨率 2160x1080 屏幕尺寸 为 6, ppi 为 403 获取到的_dpi_为 440,该分辨率下的手机 dpi 大致为 480。为什么要强调 dpi 的数值呢?我想大家都知道我们再布局的尺寸方面都会选择 dp,因为 dp 是会随着分辨率的不同而变化的,一般的关系如下:


dpi 120 : 1dp = 0.75px;dpi 160 : 1dp = 1px;dpi 240 : 1dp = 1.5px;dpi 320 : 1dp = 2px;dpi 480 : 1dp = 3px;dpi 640 : 1dp = 4px;


计算公式:px = density * dp;dp = px / density;density = dpi / 160;


根据上面的公式可以看到 dpi 影响了 dp 转 px 的数值,所以可以说 dp 适配也就是 dpi 的适配,对于 360dp X 640dp 的设计稿来说,对应的分辨率为 1080 X 1920 和 1440 X 2560,使用的数值为 1dp = 3px。正常的机型我们使用 dp 的话基本可以完成适配,但是当碰到分辨率一样 dpi 不同的手机,比如 dpi = 440 1dp = 2.75px 或者 dpi = 420 1dp = 2.625px 的机型的时候,那就懵逼了,如一个 Button 的宽度为 100dp,再 dpi = 480 的机型中显示的宽度效果为 300px,再 dpi = 440 显示的效果宽度为 275px,这样我们的布局就会跟预期的不太一样,这是 dp 无法适配的。


另外现在主流的是大屏手机,长度方向的像素点一般大于 1920px,大致在 2040px~2880px 之间,但是宽度基本保持再 1080px,配置好的手机是 1440px,市场 90%以上主流手机宽度都是 1080px 的。如:


华为:nova 2s ,Mate 10 Pro 等等分辨率是 2160X1080 dpi = 480 ;nova 3 2340 x1080 dpi = 480;小米:MIX 2040x1080 dpi = 480, MIX2 2160x1080 dpi = 440 ,Max 2160X1080 dpi = 480 等等;oppo:R11s 2160x1080 dpi = 480, R15 2280x1080 dpi = 480,等等...


手机 dpi 的大小决定了当前 dp 转 px 的倍数关系,目前大部分机型的 dpi 都是 480,也就是说设计图上一个组件的 margintop 为 100dp = 300px,那么当运行在分辨率为 1080X2280 的机型中该组件相对于设计图的位置就会偏上,在分辨率为 1080x1920 的机型中正常,这就会导致一个问题,在大屏手机中正好显示完整的布局会再小屏幕中就会出现控件被遮挡或者控件的高度比不一致,最明显的就是开屏页的 logo 位置。这也是 dp 无法解决的适配问题。


个人而言,适配宽度用 dp 基本能够适配,毕竟那些特殊 dpi 的机型还是少数,写布局注意点的话就不会出现太明显的适配问题。适配高度就需要使用其他的更有效的适配方式了。

三 宽高限定符,AndroidAutoLayout,smallestWidth,今日头条适配方案怎么取舍?

宽高限定符适配和 smallestWidth 适配方案大致思想都是一样,smallestWidth 比宽高限定符更加的智能可靠。但是这两种方案需要增加好多资源文件,想要适配什么屏幕就要去配置该类型的资源文件,全局适配。这两种适配方案再宽高适配上还是很有效果的。鸿神的 AndroidAutoLayout 已经停止维护了,我想大家都不会优先考虑这个方案了,这里也不去讨论。今日头条适配方案我想大家都或多或少的了解过,该方案还是比较精简灵活的,可以自己选择以宽度适配还是高度适配,下面是在高度纬度上面的测试数据:


设计图:360dp X 640dp 分辨率为 1080 X 1920 这里的屏幕高度包括状态栏。控件高度为 103dp 高度/屏幕高度 = 0.1609375.


模拟器 1:分辨率为 1080 x 2280 .实际是 1080 X 2136 .状态栏高度 Wie:72px.


控件高度为 103dp 高度/屏幕高度 = 0.1497093. 适配后:0.1609649.


模拟器 2:分辨率为 1080 x 1920 .实际是 1080 X 1776 .状态栏高度 Wie:72px.


控件高度为 103dp 高度/屏幕高度 = 0.18133803.适配后:0.16035.


模拟器 3:分辨率为 480 * 800.状态栏高度 Wie:36px. 尺寸小于设计图的.控件高度为 103dp 高度/屏幕高度 = 0.19375. 适配后:0.16125.


小米 4:分辨率为 1080 x 1920 .状态栏高度 Wie:60px.


控件高度为 103dp 高度/屏幕高度 = 0.16612904. 适配后:0.1609375.


小米 MIX2:分辨率为 1080 x 2160 .状态栏高度 Wie:66px. 底部虚拟导航键高度为:130px


控件高度为 103dp 高度/屏幕高度 = 0.13940887. 适配后:0.16108374.


OPPO R15:


分辨率 1080 x 2280. 尺寸是 6.28 . 状态栏高度为:84px.控件高度为 103dp 高度/屏幕高度 = 0.13552631. 适配后:0.1609649.


华为 p20:分辨率为 1080 x 2240 .状态栏高度 Wie:85px.


控件高度为 103dp 高度/屏幕高度 = 0.13770053.适配后:0.16087344.


oppo R9s:分辨率为 1080 x 1920 .状态栏高度 Wie:54px.


控件高度为 103dp 高度/屏幕高度 = 0.1609375. 适配后:0.1609375.


用今日头条的适配方案后再大屏手机中的高度比基本等于设计图中的高度比,这样在屏幕高度相差很大的真机环境中显示效果会好很多。今日头条适配方案更加的灵活,我们再适配的时候虽然是全局的修改,但是我们可以指定特定的界面上不适配(也就是把设置恢复为默认的设置),这样即使是第三方的界面只要有代码就可以选择适配适配。另外还可以的自由的配置是以宽度为基准还是以高度为基准点去适配,但是两者不能兼得。

四 今日头条适配方案到底可行吗?

那么问题来了,再日常开发中只是适配宽度的话,遇见的需求不多,适配高度确实是遇见不少,然后我再适配高度的时候发现了问题。当我们用今日头条适配方案在高度上去适配大屏手机的话(比如分辨率为 1080X2160)那样计算出来的 dpi 的数值肯定会比原数值高好多。比如小米 MIX2 分辨率为 1080 X 2160 高度适配之后再高度纬度的 dpi 数值为 523 那么就是 100dp = 317px,正常情况的 dpi 为 440 100dp = 275px。高度适配之后对宽度方向影响很大的。对下表的数据分析能看出,目前流行机型的宽度定大部分都在 1080,高度大于 1920 的机型居多,再大屏手机里面我们要首选适配高度的问题,先来看下一个简单的适配问题。


需求: 开屏页 logo 展示位置。


设计稿: 1080px X 1920px 360dp X 640dp。


logo: 大小 100dp X 100dp 水平居中,marginTop100dp。topMargin / 屏幕高度:0.15635。


测试机型: 小米四(1080X1920) vivo x21(1080X2280)。


真机数据未适配前:



未适配前:小米 4:


10-12 10:28:25.146 12746-12746/cn.screen.adaptation E/WANG: getWidth30010-12 10:28:25.146 12746-12746/cn.screen.adaptation E/WANG: getHeight30010-12 10:28:25.146 12746-12746/cn.screen.adaptation E/WANG: topMargin / 屏幕高度 0.15625


VIVO X21:10-12 10:31:15.246 23724-23724/cn.screen.adaptation E/WANG: getWidth30010-12 10:31:15.246 23724-23724/cn.screen.adaptation E/WANG: getHeight30010-12 10:31:15.246 23724-23724/cn.screen.adaptation E/WANG: topMargin / 屏幕高度 0.13157895


我们可以看到小米 4 手机的 topMargin / 屏幕高度跟设计图的一致。VIVO X21 就相差很大了。这样显示出来的 logo 的位置就会跟设计图设计的有很大的差距,这种差距是随着手机竖直分辨率的增大而增大。


真机适配后:



高度适配后:小米 4:


10-12 10:28:25.146 12746-12746/cn.screen.adaptation E/WANG: getWidth30010-12 10:28:25.146 12746-12746/cn.screen.adaptation E/WANG: getHeight30010-12 10:28:25.146 12746-12746/cn.screen.adaptation E/WANG: topMargin / 屏幕高度 0.15625


VIVO X21:10-12 10:30:33.760 23502-23502/? E/WANG: getWidth35610-12 10:30:33.760 23502-23502/? E/WANG: getHeight35610-12 10:30:33.760 23502-23502/? E/WANG: topMargin / 屏幕高度 0.15614036


我们可以明显的看到 logo 的 topMargin / 屏幕高度基本跟设计搞的一致,这样就达到了 logo 在大多数机型上面显示的效果跟设计稿的一样。但是可以发现 logo 的宽高都增加了 56px,这也是因为适配高度的时候更改了 dpi 的数值,dpi 的数值偏大就会造成全局的 dp 转 px 的倍率变大,这样我们的 logo 的大小和该界面的其它的控件的大小都会有影响。

总结:

屏幕适配任重而道远,我们要针对设计稿,针对界面,针对控件去选择我们的适配方式,技术好并不代表好用,有的时候会反其道而行之。本人还是很喜欢今日头条适配方案的,用注解做起来逼格瞬间提升,想再那个界面适配就在那个界面适配,想取消适配就取消适配,也就一个注解的事。另外还有一点就是,适配方案推出那么多时间也不短了,有几个开发者实战了呢?所谓实践出真理今日头条适配方案坑很多,我们一起慢慢踩~~欢迎大家提出文章里面的错误,大家共同学习!


参考 developer.android.google.cn/guide/pract…


欢迎关注:

我的掘金

我的简书

我的CSDN

我的Github

注解版今日头条适配方案 (供参考学习)

五 主流机型

注: 以下机型的 dpi 数值只有一部分得到真机验证,其余存在些许误差望更正,体现在(宽/density)这个数值上。

华为-荣耀系列:


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


5.9 | 360dp | 640dp || 华为 Mate 20 | 2560x1440 | 482 | 6.1 | 360dp | 640dp || 华为 Mate RS 保时捷版 | 2880x1440 | 537 | 6 | 360dp | 720dp |

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android屏幕适配前先了解这些,在阿里工作5年了