android开发根据分辨率设置高度,最详细的Android屏幕适配方案分析

为什么要屏幕适配

Android开发过程中我们常用的尺寸单位有px、dp,还有一种sp一般是用于字体的大小。但是因为px是像素单位,比方我们通常说的手机分辨例如1920*1080都是px的单位。现在Android屏幕分辨率碎片化720x1280、1080x1920、2280x1080,这就造成例如187px会在各个分辨率的机型上都是显示一样大小的,那一定不是我们想要的效果,所以用px单位我们是难以达到适配效果的,那么为什么用dp可以呢?

使用px单位从左到右依次为 480 * 800、1080 * 1920、1440 * 2560

4400700061ca6c5b892d5e601cc93f49.png

使用dp单位从左到右依次为 480 * 800、1080 * 1920、1440 * 2560

fddfcc2cfbaee596695cd8fbc9922122.png

屏幕总宽度依次为 320dp、415dp、411dp

那么什么是dp?

dp指的是设施独立像素,以dp为尺寸单位的控件,在不同分辨率和尺寸的手机上代表了不同的真实像素,比方在分辨率较低的手机中,可能1dp=1px,而在分辨率较高的手机中,可能1dp=2px,这样的话,一个187dp高度的控件,在不同的手机中就能体现出差不多的大小了。

dp如何计算成px

android中的dp在渲染前会将dp转为px,计算公式:px = density * dp;

density = dpi / 160;

px = dp * (dpi / 160);

而dpi是根据屏幕真实的分辨率和尺寸来计算的,每个设施都可能不一样的。

a3de31cb8fb77dd42306ea2590a74782.png

因为density不是固定不变的,所以每个分辨率不同的设施他们的density都一定不相等,这样就会造成每个设施的宽/高对应的总dp都是不同的,假设480 * 800分辨率的density是1.5,1080 * 1920分辨率的density是2.6,1440 * 2560分辨率的density是3.5。那么它们对应的宽度总dp = (宽度px) / density,分别为320dp、415dp、411dp。可以看出单位为dp的时候三个设施之间的差距就不是很大了,但是这样一定还是不能满足我们对屏幕适配的要求的。下面来看看Android常见的三种比较成熟的屏幕适配方案,并分析这几种方案的优劣。

屏幕适配方案

1.1 宽高限定符适配

fb8566c24fe51a55e557239b5a238fc7.png

设定一个基准的分辨率,也就是设计图对应的分辨率,其余分辨率都根据这个基准分辨率来计算,在不同的尺寸文件夹内部,根据该尺寸编写对应的dimens文件。

比方我们的设计图 375 * 667为基准分辨率宽度为375,将任何分辨率的宽度整分为375份,取值为x1-x375

高度为667,将任何分辨率的高度整分为667份,取值为y1-y667

那么对于1080*1920的分辨率的dimens文件来说,x1=(1080/375)*1=2.88px

x2=(1080/375)*2=5.76px

y1=(1920/667)*1=2.87px

y2=(1920/667)*2=5.75px

当代码里面引用高度为y_187,在APP运行时会根据当前设施分辨率去找对应xml文件中对应的高度,我们即可以按照设计稿上的尺寸填写相对应的dimens引用了,这样基本处理了我们的适配问题,而且极大的提升了我们UI开发的效率。

验证方案

简单通过计算验证下这种方案能否能达到适配的效果,例如设计图上有一个宽187dp的View。

480 * 800设计图占宽比: 187dp / 375dp = 0.498

实际在480 * 800占宽比 = 187 * 1.28px / 480 = 0.498

1080 * 1920设计图占宽比: 187dp / 375dp = 0.498

实际在1080 * 1920占宽比 = 187 * 2.88px / 1080 = 0.498

计算高同理

但是这个方案有一个致命的缺陷,那就是需要精准命中才能适配,比方1920x1080的手机就肯定要找到1920x1080的限定符,否则就只能用统一的默认的dimens文件了。而使用默认的尺寸的话,UI就很可能变形,简单说,就是容错机制很差。

1.2 smallestWidth适配

1c82f1d738549b47c421f01831269dd3.png

smallestWidth适配,或者者叫sw限定符适配。指的是Android会识别屏幕可用高度和宽度的最小尺寸的dp值(其实就是手机的宽度值),而后根据识别到的结果去资源文件中寻觅对应限定符的文件夹下的资源文件。

这种机制和上文提到的宽高限定符适配原理上是一样的,都是系统通过特定的规则来选择对应的文件。

可以把 smallestWidth 限定符屏幕适配方案 当成这种方案的更新版,smallestWidth 限定符屏幕适配方案 只是把 dimens.xml 文件中的值从 px 换成了 dp,原理和使用方式都是没变的├── src/main│ ├── res│ ├── ├──values│ ├── ├──values-sw320dp│ ├── ├──values-sw360dp│ ├── ├──values-sw400dp│ ├── ├──values-sw411dp│ ├── ├──values-sw480dp│ ├── ├──...│ ├── ├──values-sw600dp│ ├── ├──values-sw640dp

验证方案

1920 * 1080分辨率的手机,dpi为420,我们同样设置一个View为187dp宽density = (dpi = 420) / 160 = 2.6

屏幕总宽度dp = 1080 / density = 415

找到文件夹values-sw410dp下的187dp = 204.45dp

通过公式px = density * dp,计算出px = 531.57

算出占屏幕宽度的比例,56.86 / 1080 = 0.492

1440 * 2560分辨率的手机,dpi为560,我们同样设置一个View为187dp宽density = (dpi = 420) / 160 = 3.5

屏幕总宽度dp = 1440 / density = 411

找到文件夹values-sw410dp下的187dp = 204.45dp

通过公式px = density * dp,计算出px = 715.57

算出占屏幕宽度的比例,715.57 / 1440 = 0.496

由于识别的文件夹是values-sw410dp的文件夹,但是屏幕宽度为415dp和411dp,所以最后计算出的占比会有一点点误差,基本可以忽略不计,可以达到相比照较精确的适配效果

优点非常稳固,极低概率出现意外

不会有任何性能的损耗

适配范围可自由控制,不会影响其余三方库

在插件的配合下,学习成本低

缺点侵入性高,在所有地方都需要引用。

还是没有办法覆盖所有的机型分辨率,部分机型可能适配效果还是不佳

不能以高度为基准进行适配

生成很多文件,增大APP体积1~2M

1.3 今日头条适配方案

fca2e03e8a20d697dfcd9768c8290fb6.png

今日头条屏幕适配方案的核心原理在于,根据以下公式算出 density

默认px = density * dp,也就是屏幕总宽度dp = 屏幕宽度px / density,这个时候我们假设所有设施上的屏幕总宽度dp会等于我们设计图375dp,那么可以得出一个公式:

density = 屏幕宽度px / 设计图宽度(375dp)

而后我们通过系统api,将density赋值给系统,抛弃掉系统默认计算density的计算公式。

这样可以很巧妙的实现屏幕适配,而且侵入性极低,甚至可以忽略不计。

验证方案

1920 * 1080分辨率的手机,我们同样设置一个View为187dp宽,设计图宽度为375dpdensity = (屏幕宽度px = 1080) / 375 = 2.88

View宽度 = density * 187dp = 538.56

算出占屏幕宽度的比例,57.6 / 1080 = 0.498

1440 * 2560分辨率的手机,我们同样设置一个View为187dp宽,设计图宽度为375dpdensity = (屏幕宽度px = 1440) / 375 =3.84

View宽度 = density * 187dp = 718.08

算出占屏幕宽度的比例,718.08 / 1440 = 0.498

可以看出,这种方案是完全没有误差的,而且侵入性极低,只要要修改系统的density。尽管修改系统的density属性会产生一小部分影响,但是基本都是很好处理的。

优点使用成本非常低,操作非常简单

侵入性非常低

可适配三方库的控件和系统的控件

缺点会全局影响APP的控件大小,例如少量第三方库控件,他们设计的时候可能设计图尺寸并不是像我们一样是375dp,这样就会导致控件大小变形等少量问题。

最后

21427fd6beac7e8130abd5591e796fad.png

最后文末放上一个技术交流群:Android IOC架构设计

群内有许多技术大牛,有任何疑问,欢迎广大网友一起来交流,群内还不定期免费分享高阶Android学习视频资料和面试资料包~

再推荐一篇文章:“寒冬未过”,阿里P9架构分享Android必备技术点,让你offer拿到手软!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值