一、多机型 UI 适配
在 Android 开发的工作日常中,UI 适配是一件比较重要的事情。一般开发新的功能,有新的页面,最终开发完成发布之前,都需要让设计师来审 UI 效果。
而有时候,明明我们已经在一款标准的 3 倍手机上,做到了让设计师小姐姐满意的效果,但是当换了另外一台手机的时候,效果又不那么如意。
传统的做法是,拿到效果不对的手机,单独适配看看是不是哪里布局写的不对导致效果不正确,然后改正它。但是总能碰到我们拿不到真实设备的情况。
本文就介绍一个命令,可以修改你当前设备的参数,来模拟出目标设备的显示效果,让你独立就把多机型 UI 效果确认的事情给做了。
二、WM 命令
2.1 什么是 WM 命令
说的这么厉害,实际上需要使用的就是一行 wm 命令,可以通过 adb shell
来操作它。
wm 命令主要用来帮助我们修改一些屏幕的参数,先来看看它的文档。使用 adb shell wm
命令,可以方便的查看 wm 的文档描述
可以看到,wm 命令可以帮助我们修改当前设备的 size 、 density 等参数,而这两个参数就是决定了当前设备的显示效果。
2.2 WM 的命令
从上面的文档可以看出,它其实支持的命令还是挺多的,但是有一些根本用不上,是需要系统权限的,所以正常来说我们是无法使用的。那么,还是介绍几个比较实用的命令。
以下例子都是在一款标准 density 为 3 的设备上运行的,屏幕像素为 1080px * 1920px。
1、wm size
wm size
命令,可以用来查询和修改当前设备的尺寸,如果想要修改尺寸,可以使用 px 或者 dp 为单位(默认为 px),使用 x 进行连接,这个其实看看 wm size
的输出,你就清楚了。
在这里的例子中,做了几件事情:
-
使用
wm size
命令查看当前设备的尺寸。 -
使用
wm size
命令将当前尺寸修改成了 1000x2000。 -
再次使用
wm size
命令查看当前设备的尺寸。 -
最后使用
wm size reset
命令,将屏幕尺寸还原。 -
再用
wm size
命令,查看还原后的尺寸。
这几个步骤就已经涵盖了 wm size 命令的所有使用步骤,可以使用它查看当前屏幕尺寸,并且修改屏幕尺寸和还原它。
2、wm density
wm density
命令,可以用来查看和修改当前设备的 density 参数。
使用起来很简单,直接上命令了。
在这个例子中,我做了几件事情:
-
使用
wm density
查看当前设备的 density。 -
在使用
wm density
命令,修改当前设备的 density 为 420。 -
然后再使用
wm density
查看修改后的参数。 -
最后使用
wm density reset
将设备的 density 还原。 - 最后再查看一下还原后的值。
3、wm overscan
wm overscan
命令,可以修改当前设备的屏幕内边距。其实我觉得这个命令没什么用处,但是还是演示一下如何使用。
在这个例子中,做了几件事情:
-
使用
wm overscan
修改边距为 20 。 -
然后使用
wm overscan reset
将其还原。
2.3 WM 命令的原理
wm 命令的逻辑非常的简单,它实际上是和 WindowManagerService 进行交互,通过 WMS 来修改屏幕相关的一些参数。
这里就不介绍完整的 wm 源码了,就以一个方法举例来看看 wm 的逻辑。这里就以 wm size
命令举例好了。
首先,看看 wm 命令的入口。
这里会初始化 mWm ,并且根据输入的参数,调用不同的方法,如果输入的是 size ,则会调用 runDisplaySize()
方法。
在 runDisplaySize()
方法中,会先判断 size 命令后面有没有跟其它参数,如果没有,则认为是一次查询操作,会将查询到的结果输出。
而如果是 reset 方法的话,就将 w 、h 这两个代表宽高的值,设置为 -1,最终会通过 mWm.clearForcedDisplaySize()
方法,将屏幕的 size 还原。
否者就从输入的参数中,通过 x 进行分割,拿到我们输入的宽高。最终通过 mWm.setForcedDisplaySize()
方法,将当前屏幕的 size 修改成我们输入的结果。
在设置size 的时候,还会通过 parseDimens()
方法,重新计算一下输入的尺寸。
从这里可以看出,它支持两个尺寸,px 和 dp ,如果如果不指定尺寸,则默认认为是 px 。
到这里就完成了一次通过 wm size
命令,修改设备屏幕参数的全过程,跟多细节可以自行查阅源码。
源码的在线地址:
三、实施修改设备参数
既然已经讲清楚 wm 命令的所有细节了,那么我们只需要拿到我们需要适配的设备的 size 和 density。就可以在我们自己的设备上模拟出对应的效果。
我这里收集了一些比较常用的设备参数,可以供大家参考一下。
- 魅族MX3:440,1080x1800
- 一加5:420,1080x1920
- 红米NOTE,320,720x1280
- 华为MATE7,480,1080x1812
- MOTO-G5,480,1080x1920
- Moto-tx1095,432,1080x1790
- Nexus5x,420,1080x1794
- Nexus6p,560,1440x2392
- 奇酷360,460,1080x1920
- VivoX5,320,720x1280
当然,最重要的是拿到公司各种 CEO、CTO、CxO 正在使用的手机参数,进行一波适配,哈哈。
下面,我们随便挑两个设备的参数进行修改,然后看看运行后的效果。
命令如下:
// 修改成 一加5
adb shell wm density 420
adb shell wm size 1080x1920
// 修改成 Moto-tx1095
adb shell wm density 432
adb shell wm size 1080x1790
下面,从做到右,分别是原本的尺寸、一加5、Moto-tx1095。
其实看着差异不大,只能说桌面布局写的挺好的,所以说,如果布局写的好的话,是可以避免在不同设备上看着很明显的不同的问题 ,就像现在这样。
四、题外话
实际上 wm 命令,也是有一些其它问题的,例如有时候通过 wm 命令修改 UI 的的时候,刷新会不及时,会卡顿,所以选择一个性能比较好的手机是一个缓解的办法。或者修改参数之后,退出 App 重新进也是一个不错的办法。
如果调整到一个太特殊的参数,例如 200x1000 这种,可能渲染起来会很奇怪。但是如果只是做一些常规设备参数的修改,只要修改值在合理的范围内,一般都是可以的。