屏幕适配
blog:
https://www.jianshu.com/p/1302ad5a4b04
https://juejin.cn/post/6844903641610977288
px=density*dp
density=dpi/160
px=dp*(dpi/160)
首先屏幕适配方案不是解决不同的设备上能否正常显示的,想达到正常显示的目标完全可以通过适配技巧实现,试问早期只有dp适配的,没有任何其他屏幕适配方案的时候,不同的设备上UI就不能正常显示了吗?
屏幕适配方案是为了解决在不同的设备上UI的一致性。
适配方案:
1.dp适配:
官方适配方案,dp会根据设备具体的dpi(density)换算成对应的px,在不同分辨率屏幕中,实际显示的尺寸大体上是一致的,但是会出现density相同而分辨率不同设备,所以不能解决所有的适配问题,但是可以结合适配技巧使用的。
2.分辨率限定符适配:
blog:https://blog.csdn.net/lmj623565791/article/details/45460089
根据基准分辨率生成不同分辨率的dimens文件,等比缩放px值,本质就是百分比适配,缺点是侵入性高,dimens文件过多,需要设备分辨率与values文件夹完全匹配才能达到适配,容错率低。
3.最小宽度限定符适配:
blog:
https://www.jianshu.com/p/1302ad5a4b04
https://juejin.cn/post/6844903681524006925
原理与分辨率限定符适配一致,前者是根据基准分辨率,最小宽度限定符适配则是根据基准最小宽度生成不同最小宽度限定的dimens文件,等比缩放dp值,本质也是百分比适配
相比分辨率限定符适配,优点是设备的分辨率过于碎片化,而主流的最小宽度(dp)则数量相对有限,所以dimens文件较少,并且在没有完全匹配的情况下也会向下寻找接近的最小宽度,有一定的容错性。缺点同样是侵入性高。
4.density适配(今日头条):
blog:https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA(原文)
根据px=density*dp,既1dp=density px,此方案的核心就是,改变了dp适配的定义,原density=dpi/160,既dp与px的关系基于设备的dpi值
导致的问题就是相同dpi的设备,相同dp值对应的px值相同,但设备的分辨率可能不同,虽然真实尺寸大体一致,但占比不同,导致UI的展示效果不同。
density适配方案即是改变了dp适配的方式,由基于dpi,改为基于设备某一方向的宽度。由设计图决定宽度为多少dp,在任何设备上,宽度都是这个dp值,
所以在不同设备上,1dp对应的px值,就是目标设备某一方向的宽度/基准宽度(dp)。
既设置density=devicePxWidth/standardDpWidth
这里说一下,为什么基准宽度用dp,不用px,因为px是个定值嘛,写多少就是多少,没有转换,当然可以自己定义一个单位比如叫pxx,这个单位写成固定值,每个设备上对应
不同的具体的px值,这个可不就是dp吗,而且还得自己实现转换的过程。
优点就是侵入性低,缺点是由于是全局更改了density,所以一些系统原生UI,和第三方库的UI,由于不是基于我们指定的基准宽度(dp)写的dp值,所以显示效果会和原先不一致。
5.pt适配(柯基库):
首先是pt的定义,pt是1英寸的1/72,既pt/72=inch,又因为dpi=px(对角线)/inch,既px=dpi*inch,既px=(dpi/72)*pt
由density适配的思路,px=density*dp,改变density,使得设计图的dp值在不同的设备上始终等于屏幕宽度。
同样的,px=(dpi/72)*pt,改变dpi,使得设计图的pt值在不同设备上始终等于屏幕宽度。
那么只需要将dpi=72*(devicePxWidth/standardPTWidth)
既然都一样为何要用pt,因为density适配方案的缺点是density被改变,导致系统UI,第三方UI和原效果不一致,那么只要不改变density,就可以避免这个问题。
接下来就是怎么用
其实这样的方案,不管是density适配,还是pt适配,跟设计用什么单位已经没有关系了
因为dp,pt和px的对应关系,是我们自己决定的
所以不管设计图给是1080x1920px,还是1080x1920dp,也好
我们用哪种方案,就把他当成dp,pt的基准就行,基准宽度就是1080dp/pt
计算出不同设备px和dp,pt的对应关系以后,那么所有UI和设备适配宽度的比值,都是一致,这就完成了适配。
唯一的问题就是如何预览,因为一致性的效果要运行起来,动态计算才会呈现。
答案就是创建比值为1,既1px=1dp,1px=1pt的虚拟设备来预览。
这样预览的效果和设计图就是一致的。
接下来的问题就是,如何创建pt适配的虚拟设备,在长宽已知的前提下,还要屏幕尺寸参数。
因为我们的目标是创建1px=1pt的设备。
所以,px=(dpi/72)*pt,可以等出虚拟设备的dpi为72
因为dpi=(√w^2+h^2)/inch,故虚拟设备的尺寸为inch=(√w^2+h^2)/72