一部手机做好屏幕适配
来源:互联网 发布:菜鸟手机助手源码 编辑:程序博客网 时间:2024/04/30 03:29
一.Android多机型适配:
多机型适配在Android开发中经常会碰到,那么如果我们只有一部测试机,如何能做到用这一部手机来看各种不同分辨率手机的UI显示呢!不需要桌前摆一排手机来一个一个的是看。
二.WM命令:
1.什么是WM命令:
说了这么多前提,实际上需要使用的就是一行 wm命令,可以通过 adb shell来操作它。
wm 命令主要用来帮助我们修改一些屏幕的参数,先来看看它的文档。使用 adb shell wm命令,可以方便的查看 wm的文档描述
可以看到,wm命令可以帮助我们修改当前设备的 size、 density 等参数,而这两个参数就是决定了当前设备的显示效果。
2.2 WM命令
上面的文档中有很多命令,其实我们平时用到的一般只有size,density这两个,以下例子为一部1080x1920的设备:
1. wm size命令
wm size命令,可以用来查询和修改当前设备的尺寸,如果想要修改尺寸,可以使用px 或者dp 为单位(默认为 px),使用x 进行连接,这个其实看看wm size的输出,你就清楚了。
上面的例子中,调用了不同的命令:
1.使用wm size 命令查看当前设备的尺寸。
2.使用wm size 命令将当前尺寸修改成了 1000x2000。
3.再次使用wm size 命令查看当前设备的尺寸。
4.最后使用wm size reset 命令,将屏幕尺寸还原。
5.再用wm size 命令,查看还原后的尺寸。
这几个步骤就已经涵盖了wm size 命令的所有使用步骤,可以使用它查看当前屏幕尺寸,并且修改屏幕尺寸和还原它。
2.wm density命令
wm density 命令,可以用来查看和修改当前设备的 density 参数。
使用起来跟wm size相同,我们直接上命令吧。
在这个例子中,我做了几件事情:
1.使用wm density 查看当前设备的 density。
2.在使用wm density 命令,修改当前设备的 density为 560,580。
3.然后再使用wm density 查看修改后的参数。
4.最后使用wm density reset 将设备的 density还原。
5.最后再查看一下还原后的值。
3.wm overscan命令
wm overscan命令,可以修改当前设备的屏幕内边距。这个命令一般用不到。
在这个例子中,做了两件事:
1.使用wm overscan 修改边距为 30。
2.然后使用wm overscan reset 将其还原。
WM命令源码:
package com.android.commands.wm;2021import android.content.Context;22import android.graphics.Point;23import android.graphics.Rect;24import android.os.RemoteException;25import android.os.ServiceManager;26import android.os.UserHandle;27import android.util.AndroidException;28import android.util.DisplayMetrics;29import android.view.Display;30import android.view.IWindowManager;31import com.android.internal.os.BaseCommand;3233import java.io.PrintStream;34import java.util.regex.Matcher;35import java.util.regex.Pattern;3637public class Wm extends BaseCommand {3839 private IWindowManager mWm;4041 /**42 * Command-line entry point.43 *44 * @param args The command-line arguments45 */46 public static void main(String[] args) {47 (new Wm()).run(args);48 }4950 @Override51 public void onShowUsage(PrintStream out) {52 out.println(53 "usage: wm [subcommand] [options]\n" +54 " wm size [reset|WxH|WdpxHdp]\n" +55 " wm density [reset|DENSITY]\n" +56 " wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" +57 " wm scaling [off|auto]\n" +58 " wm screen-capture [userId] [true|false]\n" +59 "\n" +60 "wm size: return or override display size.\n" +61 " width and height in pixels unless suffixed with 'dp'.\n" +62 "\n" +63 "wm density: override display density.\n" +64 "\n" +65 "wm overscan: set overscan area for display.\n" +66 "\n" +67 "wm scaling: set display scaling mode.\n" +68 "\n" +69 "wm screen-capture: enable/disable screen capture.\n" +70 "\n" +71 "wm dismiss-keyguard: dismiss the keyguard, prompting the user for auth if " +72 "necessary.\n"73 );74 }7576 @Override77 public void onRun() throws Exception {78 mWm = IWindowManager.Stub.asInterface(ServiceManager.checkService(79 Context.WINDOW_SERVICE));80 if (mWm == null) {81 System.err.println(NO_SYSTEM_ERROR_CODE);82 throw new AndroidException("Can't connect to window manager; is the system running?");83 }8485 String op = nextArgRequired();8687 if (op.equals("size")) {88 runDisplaySize();89 } else if (op.equals("density")) {90 runDisplayDensity();91 } else if (op.equals("overscan")) {92 runDisplayOverscan();93 } else if (op.equals("scaling")) {94 runDisplayScaling();95 } else if (op.equals("screen-capture")) {96 runSetScreenCapture();97 } else if (op.equals("dismiss-keyguard")) {98 runDismissKeyguard();99 } else {100 showError("Error: unknown command '" + op + "'");101 return;102 }103 }104105 private void runSetScreenCapture() throws Exception {106 String userIdStr = nextArg();107 String enableStr = nextArg();108 int userId;109 boolean disable;110111 try {112 userId = Integer.parseInt(userIdStr);113 } catch (NumberFormatException e) {114 System.err.println("Error: bad number " + e);115 return;116 }117118 disable = !Boolean.parseBoolean(enableStr);119120 try {121 mWm.setScreenCaptureDisabled(userId, disable);122 } catch (RemoteException e) {123 System.err.println("Error: Can't set screen capture " + e);124 }125 }126127 private void runDisplaySize() throws Exception {128 String size = nextArg();129 int w, h;130 if (size == null) {131 Point initialSize = new Point();132 Point baseSize = new Point();133 try {134 mWm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, initialSize);135 mWm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, baseSize);136 System.out.println("Physical size: " + initialSize.x + "x" + initialSize.y);137 if (!initialSize.equals(baseSize)) {138 System.out.println("Override size: " + baseSize.x + "x" + baseSize.y);139 }140 } catch (RemoteException e) {141 }142 return;143 } else if ("reset".equals(size)) {144 w = h = -1;145 } else {146 int div = size.indexOf('x');147 if (div <= 0 || div >= (size.length()-1)) {148 System.err.println("Error: bad size " + size);149 return;150 }151 String wstr = size.substring(0, div);152 String hstr = size.substring(div+1);153 try {154 w = parseDimension(wstr);155 h = parseDimension(hstr);156 } catch (NumberFormatException e) {157 System.err.println("Error: bad number " + e);158 return;159 }160 }161162 try {163 if (w >= 0 && h >= 0) {164 // TODO(multidisplay): For now Configuration only applies to main screen.165 mWm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, w, h);166 } else {167 mWm.clearForcedDisplaySize(Display.DEFAULT_DISPLAY);168 }169 } catch (RemoteException e) {170 }171 }172173 private void runDisplayDensity() throws Exception {174 String densityStr = nextArg();175 int density;176 if (densityStr == null) {177 try {178 int initialDensity = mWm.getInitialDisplayDensity(Display.DEFAULT_DISPLAY);179 int baseDensity = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);180 System.out.println("Physical density: " + initialDensity);181 if (initialDensity != baseDensity) {182 System.out.println("Override density: " + baseDensity);183 }184 } catch (RemoteException e) {185 }186 return;187 } else if ("reset".equals(densityStr)) {188 density = -1;189 } else {190 try {191 density = Integer.parseInt(densityStr);192 } catch (NumberFormatException e) {193 System.err.println("Error: bad number " + e);194 return;195 }196 if (density < 72) {197 System.err.println("Error: density must be >= 72");198 return;199 }200 }201202 try {203 if (density > 0) {204 // TODO(multidisplay): For now Configuration only applies to main screen.205 mWm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, density,206 UserHandle.USER_CURRENT);207 } else {208 mWm.clearForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY,209 UserHandle.USER_CURRENT);210 }211 } catch (RemoteException e) {212 }213 }214215 private void runDisplayOverscan() throws Exception {216 String overscanStr = nextArgRequired();217 Rect rect = new Rect();218 if ("reset".equals(overscanStr)) {219 rect.set(0, 0, 0, 0);220 } else {221 final Pattern FLATTENED_PATTERN = Pattern.compile(222 "(-?\\d+),(-?\\d+),(-?\\d+),(-?\\d+)");223 Matcher matcher = FLATTENED_PATTERN.matcher(overscanStr);224 if (!matcher.matches()) {225 System.err.println("Error: bad rectangle arg: " + overscanStr);226 return;227 }228 rect.left = Integer.parseInt(matcher.group(1));229 rect.top = Integer.parseInt(matcher.group(2));230 rect.right = Integer.parseInt(matcher.group(3));231 rect.bottom = Integer.parseInt(matcher.group(4));232 }233234 try {235 mWm.setOverscan(Display.DEFAULT_DISPLAY, rect.left, rect.top, rect.right, rect.bottom);236 } catch (RemoteException e) {237 }238 }239240 private void runDisplayScaling() throws Exception {241 String scalingStr = nextArgRequired();242 if ("auto".equals(scalingStr)) {243 mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 0);244 } else if ("off".equals(scalingStr)) {245 mWm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 1);246 } else {247 System.err.println("Error: scaling must be 'auto' or 'off'");248 }249 }250251 private void runDismissKeyguard() throws Exception {252 mWm.dismissKeyguard();253 }254255 private int parseDimension(String s) throws NumberFormatException {256 if (s.endsWith("px")) {257 return Integer.parseInt(s.substring(0, s.length() - 2));258 }259 if (s.endsWith("dp")) {260 int density;261 try {262 density = mWm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);263 } catch (RemoteException e) {264 density = DisplayMetrics.DENSITY_DEFAULT;265 }266 return Integer.parseInt(s.substring(0, s.length() - 2)) * density /267 DisplayMetrics.DENSITY_DEFAULT;268 }269 return Integer.parseInt(s);270 }271}
根据上述源码以wm size 为例,解析下源码:
1.wm命令的逻辑非常的简单,它实际上是和 WindowManagerService进行交互,通过 WMS来修改屏幕相关的一些参数。
这里就不介绍完整的 wm源码了,就以一个方法举例来看看 wm的逻辑。这里就以 wm size命令举例好了。
首先,看看 wm命令的入口onRun()。
2.这里会初始化 mWm,并且根据输入的参数,调用不同的方法,如果输入的是 size,则会调用runDisplaySize()方法。
3.在runDisplaySize()方法中,会先判断 size命令后面有没有跟其它参数,如果没有,则认为是一次查询操作,会将查询到的结果输出。
而如果是 reset方法的话,就将 w、h这两个代表宽高的值,设置为 -1,最终会通过mWm.clearForcedDisplaySize()方法,将屏幕的 size 还原。
否者就从输入的参数中,通过 x进行分割,拿到我们输入的宽高。最终通过mWm.setForcedDisplaySize()方法,将当前屏幕的 size修改成我们输入的结果。
在设置size的时候,还会通过parseDimens()方法,重新计算一下输入的尺寸。
4.从这里可以看出,它支持两个尺寸,px和 dp ,如果如果不指定尺寸,则默认认为是 px。
到这里就完成了一次通过wm size 命令,修改设备屏幕参数的全过程
操作注意事项:
1.手机连接电脑并打开UBS调试;
2.运行自己的app;
3.打开电脑命令行进行上述命令设置,即可看到手机不同分辨率。
常用到的手机分辨率及尺寸,仅供参考:
手机型号 density size
一加5 420 1080x1920
红米NOTE. 320 720x1280
华为MATE7. 480 1080x1812
MOTO-G5 480 1080x1920
魅族MX3 440 1080x1800
Nexus5x 420 1080x1794
Nexus6p 560 1440x2392
奇酷360 460 1080x1920
VivoX5 320 720x1280
- 一部手机做好屏幕适配
- Android 手机关于屏幕适配
- Android多屏幕适配-手机
- Android多屏幕适配-手机
- Android 适配不同屏幕(手机,平板)
- HTML手机端屏幕适配
- 适配手机端屏幕js代码
- ios设计一部WindowsPhone手机
- 手机、平板多屏幕多分辨率适配
- 手机、平板多屏幕多分辨率适配
- android不同屏幕大小手机的适配问题
- 手机、平板多屏幕多分辨率适配
- 手机、平板多屏幕多分辨率适配
- 手机、平板多屏幕多分辨率适配
- html5>egret>手机浏览器处理适配屏幕问题
- 手机、平板多屏幕多分辨率适配
- Fragment同时适配手机和平板两种屏幕
- 安卓手机APK屏幕适配总结
- C#简介
- [LeetCode] 461.Hamming Distance
- ARM-CP15寄存器组介绍(开启I/D catch,MMU都需要此寄存器)
- C中double到int的转换、四舍五入
- Android开发路上遇到的坑
- 一部手机做好屏幕适配
- android自动化测试--appium运行的坑问题及解决方法
- scikit-learn 中文文档-大规模计算的策略-用户指南|ApacheCN
- 云计算之路-虚拟化环境搭建及虚拟机创建
- 获取音频的波形
- 51Nod 1265 四点共面
- TensorFlow 真正从零开始,TensorFlow详细安装入门图文教程
- Kafka 如何读取offset topic内容 (__consumer_offsets)
- Javascript(一)