Android屏幕适配解析

本文是字节跳动团队开源的屏幕适配方案的解析。

很久之前看到过字节跳动团队的屏幕适配方案,粗略看过一遍之后,感觉这个方案简直perfect,几行代码就能搞定还没性能损耗,一度想要上手对我写的App适配一下,但是我突然发现,我的App好像根本不需要适配,后来又陆陆续续的看了几次这个方案,感觉很简单,但是仔细一想,好像就不是很明白了。今天终于决定好好研究研究这个方案到底是个什么鬼,好在研究明白了,也明白为啥我写的App不需要适配了。

为什么要进行适配

首要要解决的问题就是为什么要适配,不扯什么碎片化,什么屏幕大小,屏幕密度那些个虚的,直接举个例子,假设我们的设计图如下:
在这里插入图片描述
上面的设计图,已经标注好了尺寸,三个图片,横向正好占满了屏幕的宽度。看上去没有问题,但是不同的手机可能就会出现下面的情况:
真实设备上的情况
不同手机上很有可能就是上面的情况,因为我们的屏幕宽度不一定是360dp。
但是原型图设计的时候,只能在一个固定的尺寸上进行设计,真机的情况又千千万,所以我们最后写好的界面很可能就和设计图不符了。
好的,第一个的问题为什么要适配的问题解决了。
插一句题外话,为什么我写的App不需要适配的,因为我的App界面根本就不复杂,大部分界面就是文字排列,用好dp就ok了,当然dp适配也是适配的一种。

怎么适配

具体方案参考今日头条的操作

https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA

贴一下核心的代码:

        DisplayMetrics systemDM = Resources.getSystem().getDisplayMetrics();
        DisplayMetrics activityDm = activity.getResources().getDisplayMetrics();
        
        activityDm.density = activityDm.widthPixels / 360;
        activityDm.scaledDensity = activityDm.density * (systemDM.scaledDensity / systemDM.density);
        activityDm.densityDpi = (int) (160 * activityDm.density);

原理其实就是这下面这几个公式:
px = density * dp;
density = dpi / 160;
px = dp * (dpi / 160);

px:分辨率,分辨率就是手机屏幕的像素点数。一般为屏幕的“宽×高”,例如分辨率有720×1280的手机设备,表示此屏幕在宽度方向有720个像素点,在高度方向有1280个像素点。
dp:密度无关像素,这就是开发时最常用的单位dp
dpi:这个单位是根据屏幕真实的分辨率和尺寸来计算的,每个设备都可能不一样的。
dpi的计算公式
可以看到和手机相关的就是dpi,density 。适配的入手点也就在这个地方。
我们回过头来再看下最开始的设计图:
设计图
很明显,这张图设计的时候是按照宽度为360dp来设计的。我们需要做的就是让360dp*density =屏幕真实的像素宽度。
于是思路就有了,360dp是设计的尺寸,这个不能改,屏幕的真实宽度更不可能更改,所以能改的就只有density了。
这样一来,适配方案就清晰了。于是就有了如下的代码

DisplayMetrics activityDm = activity.getResources().getDisplayMetrics();
activityDm.density = activityDm.widthPixels / 360;

设备的真实宽度/360,就是我们想要的缩放数据了,把这个数据在系统中修改就好了。
这样一来,不论手机屏幕是怎样的,我们都能保证360dp渲染之后就是屏幕的宽度。

至于代码中的activityDm.scaledDensity,这个是用来适配sp的。文字的单位我们通常用sp,因为这样用户在系统设置中修改手机文字大小的时候,我们的文字可以跟随系统大小变化。

总结

回过头来仔细想想,所有的核心都在下面这个公式上:
px = density * dp;
要保证我们规定的某个dp渲染之后就是屏幕宽度,只能去修改density,刚好这个值是可以获取并可以修改的,于是问题就迎刃而解了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值