最小宽度smallWidth适配实现屏幕适配方案
在之前的文章中,我们讲到了Android
屏幕适配的一些知识,大家感兴趣的话可参考
Android屏幕适配(1) — 概念解释
Android屏幕适配(2) — drawable与mipmap
Android屏幕适配(3) — 资源文件夹命名与匹配规则
Android屏幕适配(4) — 宽高限定符
今天就让我们来学习下Android屏幕适配的最小宽度smallWidth适配
相关知识吧。
今天涉及知识有:
之前我们已经讲过屏幕适配的原理是: px=(实际分辨率/涉及基准分辨率)*dp
,由于无法兼顾横竖两个方向,所以会采取宽,或者高的一个方向来适配。今天要讲的最小宽度smallWidth适配
与之前又有所区别。最小宽度是指对手机或平板而言,最短的两条边,不一定是屏幕的宽度。(例如对平板而言,有的高度其实是小于宽度的,这是所谓的最小宽度
其实是平板的高度
)
利用SmallWidthDimensHelper
帮助类,我们生成的values
文件夹名字类似如下:
values-sw240dp
values-sw360dp
values-sw400dp
values-sw960dp
values-sw1080dp
......
以我测试的手机为例,我手机信息如下:
*************屏幕信息*************
宽=1080 高=2032
dpi=480 density(屏幕像素比例)=3.0
smallwidthDensity(最小宽度)=360.0
**********************************
可以看到我手机屏幕尺寸: 1080x2032
,dpi=480
,density(屏幕像素比例)=3.0
,接着有一个smallwidthDensity(最小宽度)=360.0
。
这里我们需要注意的是,我手机屏幕尺寸: 1080x2032
适配的values
文件夹并不是values-sw1080dp
,而是values-sw360dp
。values-swXXXdp
文件夹格式,这里的XXX
表示的可不是屏幕宽度尺寸,而是最小宽度Density
。我们可以通过公式:
smallwidthDensity = 屏幕最短尺寸(屏幕宽高尺寸较短的那个)/屏幕像素比例(density)
来获取一个参考值。
为什么说是一个参考值呢,因为我们的手机一般默认最小宽度
我们计算的这个值,一般不会去改它,但是在手机的设置
—>系统
—>开发者模式/开发人员选项
—>最小宽度
上是显示默认最小宽度
,如下图
由上面的讲解我们已经知道,为了适配屏幕,我们会生成大批量values-swXXXdp
文件夹。类似如下:
values-sw240dp
values-sw360dp
values-sw400dp
values-sw960dp
values-sw1080dp
以我测试为例,加载的是values-sw360dp
文件夹,若项目中没有values-sw360dp
文件夹,则会向上匹配values-sw240dp
文件夹,如果values-sw240dp
文件夹没有,则会再往小的匹配,如果还是没有,则会匹配默认values
文件夹。
这里我封装了一个自动生成values dimens
文件夹的工具类。此类要在Android项目中新建一个Java_module
,然后在Java
的main
方法中执行以下调用:
public static void main(String[] args) {
System.out.println("======我是中国人=======");
SmallWidthDimensHelper helper = new SmallWidthDimensHelper();
helper.setBase(1080, 1920) //设计图基准宽高
.setDefaultScale(1.0f) //默认缩放比
.createSmallWidthDimens(); //最小宽度适配
}
以上代码的setBase(1080, 1920)
设置的是设计图即UI给出的基准屏幕宽高, setDefaultScale(1.0f)
设置的是默认values
文件夹中dp
和实际dp
的比值。
下面贴出MainActivity
中布局代码:
生成文件夹部分结构图如下:
随便打开一个dimens.xml
文件部分代码如下:
0.0dp
0.29dp
0.59dp
0.88dp
1.18dp
1.48dp
1.77dp
2.07dp
2.37dp
2.66dp
2.96dp
3.25dp
3.55dp
3.85dp
4.14dp
4.44dp
4.74dp
......
注意,这里生成的值也是dp
。
屏幕适配部分机型效果图如下:
最小宽度适配方案其实在Androidstudio
中由一个插件ScreenMatch
,其使用的话可参考