本文主要涉及以下几篇文章
Android 屏幕适配总结
Android ConstraintLayout 使用与适配(使用篇)
Android ConstraintLayout 使用与适配(适配篇)
Android 自动创建最小宽度限定符文件插件 AutoDimens
目录
一、与屏幕相关的概念
1. 屏幕尺寸
2.屏幕分辨率
3. 屏幕像素密度(dpi)
二、为什么需要适配
1.屏幕比例不同(屏幕尺寸不一样)
2.屏幕像素密度(dpi)不同
三、Android 屏幕适配原因
四、官方推荐方式 —— dp
具体分析
五、dp + 修改 density 值适配
一、在 Application 中修改 density 适配
二、在 Activity 中修改 density 适配
三、使用 dp + 修改 density 适配的弊端
六、官方推荐方式 —— 最小宽度限定符适配
一、最小宽度
二、限定符
三、原理解析
四、使用
七、官方推荐方式 —— ConstraintLayout
八、总结
1.建议
2.各适配方式优缺点
与 Android 适配相关的文章有很多,其中也有不少好文章,对我的受益很多,可还是有些点不是很明白,因此自己亲自验证并总结成本文。
1. 屏幕尺寸
屏幕大小单位(如平常说的 55寸电视、5寸手机),统一度量单位 (英寸),测量方式是屏幕对角线的长度为几英寸就是几寸屏。
1英寸=2.54厘米(cm)
2.屏幕分辨率
屏幕横向、竖向显示的像素数。如分辨率为1080x1920 的屏幕,即为横向1080个像素点,竖向1920个像素点的屏幕。
3. 屏幕像素密度(dpi)
屏幕每英寸显示的像素点数,在同一尺寸下,分辨率越高,屏幕越清晰,dpi越高。得到屏幕像素密度的计算方式如下
我看到的文章大部分是说 Android 屏幕碎片化严重所以需要适配。可碎片化只是一种客观存在的现象。而 Android 之所以需要屏幕适配的主要原因有两个:
1.屏幕比例不同(屏幕尺寸不一样)
屏幕比例不同,即屏幕宽高比不同,(就是宽高的不同)。屏幕比有很多,如:4:3、5:4、16:10、16:9 等。如在同密度、同尺寸的情况下,屏幕比不同会出现宽高不一至的情况,如下图示例
在同样的5.5寸屏,宽高比分别是 16:9,7:6,最终两个屏幕的大小不一样,这样画一条360px的直线,在图3就是满屏,在图4就只占屏幕的四分之三,而同样的内容可以在图3中显示下,在图4中就有可能超过底部边缘显示不下。这在一些情况下就需要适配屏幕以保证与设计图一致。
2.屏幕像素密度(dpi)不同
屏幕密度不同,即设备分辨率的不同,如在同尺寸的屏幕中,不同分辨率会使屏幕密度不同。如下图示例
在上面两个图中,屏幕的尺寸、比例,都是一样的,但是分辨率是不一样的,这就造成屏幕密度不一样。这样画一条 360px 的直线,在图5中是满屏,在图6中就只有三分之一,在图6中可以显示的内容,在图5中就有可能超过底部边缘,显示不下。这种情况也是造成需要适配的原因。
总结一下适配的 2 个主要原因
1.屏幕像素密度不一样
2.屏幕比例不同(屏幕尺寸不一样)
其实适配,主要是针对这两点进行适配的。理解了屏幕的概念,知道了适配屏幕的原因,这样处理问题就有了方向。下面说说几种官方推荐的主流适配方式,与民间使用比较多的适配方式。
dp 是 Android 里的一个与像素密度无关的单位,因此 Google 推荐使用 dp 解决屏幕像素密度不一样的场景,就是上面所说的第 1 个原因。
dp 为什么可以解决这个像素密度引起的适配问题呢?是因为程序运行后,Android 会根据当前屏幕密度(dpi)将布局文件中的 dp 值转换为 px 值显示在屏幕上。调整公式是:px = dp * (dpi / 160)。
总结:Android 默认会将屏幕密度为 160dpi 的屏幕定为基准(注意:与屏幕分辨、屏幕尺寸没有任何联系,此处不要与其他两个概念联系起来,他们之间没有任何的影响)。这是什么意思呢? 也就是说我们在布局文件中写的 12dp、13dp、等以 dp 为单位的值。Android 默认此布局文件是一个运行在屏幕像素密度为 160dpi 屏幕的布局文件。如果真实运行后屏幕像素密度不是 160 dpi 的屏幕,此时 Android 会以 160 dpi 为基准,将布局文件中 dp 单位的尺寸调整大小,而这个调整的公式就是:px = dp * (dpi / 160)。
这一点我们可以用事实证明一下,在同一分辨率 (360x640),不同像素密度 160 dpi 和 280dpi 的屏幕下,分别画一条 120px 和一条 120dp 的直线,效果如下:


首先看以 dp 为单位的使用结果
图1 中可以证明在像素密度为 160 dpi 的屏幕下,px 单位与 dp 单位是一致的,即 1dp = 1px (说明:这与屏幕分辨率无关,就算是在 1080*1920的屏幕下,只要像素密度是 160dpi,那 1dp 就等于 1px)。
而在像素密度为 280 dpi 的屏幕中 120dp 的直线转换为 px,利用公式:px = 120dp * (280dpi / 160),实际像素是 210px。这就是 图2 中 120dp 实际显示的像素数。
再来看以 px 为单位的使用结果
图1、图2中,在不同像素密度的屏幕下,使用 px 为单位的直线,显示结果居然是一样的(这是句费话),px 本身与像素密度是无关的,在同样大的分辨率(360x640)屏幕下,使用 px 为单位,显示结果当然是一样的。