joy keeps flowin'

Android屏幕适配和最小宽度

xx
目次

凡事总要问为什么。为什么需要屏幕适配? 众所周知,Android是一个较开发的系统,允许各家厂商定制修改AOSP,选用不同规格的硬件,包括CPU、内存、电池、传感器等等等等。当然屏幕也在其中。也因此,大家手上的手机屏幕大不相同,体现在屏幕的尺寸、分辨率上。

屏幕尺寸 #

屏幕尺寸是指从屏幕左上角到右下角这条对角线的距离,单位是英寸(inch)。

屏幕尺寸和分辨率

px #

如果你对图像有了解,px(pixel)是图像的基本单位,当一张图片放大到不能再放大之后,图像中最小的一个色块就是px。一个像素只能显示一个颜色,许许多多像素放在一起,从宏观上看就是有变化的图片。

值得注意:px不具有固定的大小,只是一个显示的最小单位。

分辨率 #

前面说px是图像的最小单位,手机屏幕图像的最小单位当然也是px,屏幕上有多少个px呢?这就是分辨率。 通常用横竖有多少个px表述分辨率,比如:

在上面的图片中也就是纵向有1920px,横向有1080px,共1920x1080个。

分辨率多对屏幕适配有什么影响呢? 试想一下:有两个设备,一个设备A屏幕的分辨率是1280x720,而另一个设备B屏幕是1920x1080。假设我想写一个View,宽度占屏幕宽度的一半(短的一个边),都用px写布局时,一个是360px,另一个是540px,我需要写两套布局。

dp #

dp(Density-Independent Pixels)中文像素无关密度,表示一英寸的屏幕上有多少个像素,把分辨率和物理屏幕大小联系起来,类似其他的密度,不过是把计算密度的方式换成屏幕的。与px的计算方式:px = dp * (dpi / 160)

dpi和160又是什么东西呢?dpi是像素密度,计算方式为:

ppi

图片中的ppi为:

Imgur

ppi和dpi是两个不同的概念,暂且理解成是一样的。

而160是基准的像素密度。

为什么是160看到说法没找到官方文档,如果你看到了烦请分享出来

就相当于,认为160的密度是标准的,比这个值大的,就表示一英寸这个单位上像素数量要多。屏幕尺寸相同的情况下,这个屏幕就有更高的分辨率,要容纳下这些像素,肯定是要要在一英寸上放下更多的像素了。

dpi / 160就表示要容纳多少倍的像素,再*dp就表示一英寸上实际有多少px。

用dp写布局就能解决在设备A和设备B上适配的一部分问题。在设备A的dpi是设备B的dpi 1.5倍时,两个设备换算出宽度的dp值是相同的,这时用dp就能用一套布局在两个不同设备上有相同的显示效果。

显示效果示例

你可能发现了规律,设备A是设备B的屏幕尺寸、宽、高都缩放1.5的结果。如果不都是成比例的呢?

最小宽度(sw) #

最小宽度方案是使用最多的方案。

系统会根据当前设备屏幕的 最小宽度 来匹配 values-swdp,用最小宽度是因为最小宽度不会随着旋转屏幕变化。

以一个最小宽度作为基准,比如最小宽度基准是360dp,把屏幕分成360份。最小宽度是400dp时,把400分成360份,那么每一份是基准的1.11倍,sw400的dimen值就是sw360对应的1.11倍。在sw360中的1dp在sw400中要用1.11dp。

关于最小宽度更详细参见骚年你的屏幕适配方式该升级了!-smallestWidth 限定符适配方案

补充 #

官方匹配规则 #

官方匹配规则是将多个配置限定符按照优先级先后拼接在一起,从前往后匹配,是可以向下兼容的,但是只要遇到一个不兼容的配置限定符就会回退。

举个例子,现在项目中有两个layout文件夹,分别是layout-sw540-v31和layout-sw600-v33,设备的版本是32,分辨率是1920x1080,dpi是320,最小的宽度是1080px,计算出sw对应的dp是540。按照优先级sw比版本要高,优先匹配sw540,32和31、33都不同,但是刚刚说过是可以向下兼容的,因此可以命中layout-sw540-v31。

sw计算 #

官方文档:

应用可用屏幕区域的最短尺寸。具体而言,应用窗口的 smallestWidth 是窗口可用高度和宽度的最小尺寸。您也可将其视为窗口的“最小可能宽度”。您可使用此限定符,让应用界面的可用宽度至少为 dp。

sw的单位是dp,二分辨率的单位是px,所以需要转换为dp。还用刚刚例子中的设备,最小的宽度是1080培px,假设dpi是320,计算dp的公式是px = dp * (dpi / 160),那么计算dp的公式就是dp=px / (dpi / 160),1080/(320/160),sw的结果就是540。

相关adb命令:

1
2
3
4
5
# 设备分辨率
adb shell wm size

# 查看屏幕密度(DPI)
adb shell wm density

插件仓库 #

Github仓库 按照上面最小宽度计算规则,帮我们为不同的屏幕密度生成对应的dimens文件夹,

参考 #

标签:
Categories: