始终以真实屏幕的最小宽度作为匹配计算,无论横竖屏转变都是以最小宽度为准匹配
实际适配调试经验:
因为适配过程中可能会动态的调节设备像素和密度。根据如下工具代码打日志,可以快速调试当前设备。
package com.jicaai.radio.utils;
import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import com.jicaai.radio.R;
public class ScreenMatchUtil {
public static void log(Activity context) {
// px的全称是( pixel ), 即像素的意思;
//我们常数的 480*800 、720*1280、1080*1920指的就是像素值宽高的意思;
//指屏幕是由多少个象数点所组成;
//在实际编程中,我们通常不使用该单位;比如,我们指定一张图片的大小是240*400px,它在480*800的手机屏幕上占的大小是一半,而在1080*1920分辨率的手机屏幕上,这张图片占有的空间连1/4都不到,这样就造成兼容性事故;
//但是在某些特定情况下,使用PX会具有优势,比如设置一道分割线,原因将在下一节解释完dp后给出;
//使用方法如下(这里分别是px和dp,解释在下一节):
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int API_LEVEL = android.os.Build.VERSION.SDK_INT;
// 方法1
DisplayMetrics displayMetrics = new DisplayMetrics();
if (API_LEVEL >= 17) {
display.getRealMetrics(displayMetrics);
} else {
display.getMetrics(displayMetrics);
}
// 首先 dp=dip,老版本的Android系统中,常用dip,现在都用dp;
//dp也是一种像素,全称“Device-Independent Pixel”,叫“设备独立像素”,这个值和“像素密度”有关;
//先来说说这个“像素密度”,简称是dpi,全称是( Dots pre Inch),即每一个英寸屏幕包含的像素点数,这个值和手机的物理尺寸相关联;
//px像素只说明了一个屏幕包含的点数有多少,但是点的大小不是确定的,同样是480*800,可能是手掌那么大,也可能是电影院屏幕那么大;
//现在引入像素密度,用每英寸包含的像素数目,来衡量屏幕的质量水准;
//一部横向宽度2英寸、480像素的手机,它的横向像数密度就是 480/2 = 240dpi ;
//可以看出,“设备独立像素”是一个常量;
//获取像素密度的方法是:
int densityDpi = displayMetrics.densityDpi;
// SP的全称是“ScaledPixels”,即放大像素;
//Android的系统,允许字体自由缩放,在整个屏幕大小不变、像素不变的情况下,字体可以进行缩放;这样,字体的大小就和之前的英寸,像素,设备独立像素,密度都没有关系了;这个 “放大像素”和另一个参数“缩放密度(scaledDensity)”有关;
//在实际编程中,我们通常将字体使用sp单位,以适应不同屏幕分辨率;
float scaledDensity = displayMetrics.scaledDensity;
String param = "px=" + displayMetrics.widthPixels + "*" + displayMetrics.heightPixels + " dp(dip)=" + densityDpi
+ " ,smallDp=" + displayMetrics.widthPixels * 160 / densityDpi + "*" + displayMetrics.heightPixels * 160 / densityDpi
+ "\n sp=" + scaledDensity + " density=" + displayMetrics.density + " scaledDensity=" + displayMetrics.scaledDensity + " xdpi=" + displayMetrics.xdpi + " ydpi=" + displayMetrics.ydpi
+ "\n current dp1="+context.getResources().getDimension(R.dimen.dp1)+",match dp="+String.valueOf(context.getResources().getDimension(R.dimen.dp1)/displayMetrics.density);
Log.e("screen_param", param);
}
}
日志打印如下
screen_param: px=1080*2400 dp(dip)=440 ,smallDp=392*872
sp=2.75 density=2.75 scaledDensity=2.75 xdpi=394.705 ydpi=394.563
current dp1=1.4091,match dp=0.51240003
1、 根据dp1知道1个dp为1.4091个像素,根据match dp然后去查看匹配文件知道是values-sw392dp文件下的值。
2、以打印的smallDp中最小值为准匹配,真实手动计算的最小宽度和设备中获取的不一样
3、开发过程中以设计图中的标注为准写入标准dimens文件,screenMatch.properties中配置base_dp也以设计图中的最小宽度为准
二 ScreenMatch如何使用
在 Android Studio 中安装 ScreenMatch 插件
下载插件 ScreenMatch 到本地,点击菜单栏上的 File -> Settings -> Plugins -> Install plugin from disk,然后选择我们刚刚下载的插件,最后点击 “OK”,重启 Andorid Studio 即可。如下图所示:
在项目的默认 values 文件夹中需要一份 dimens.xml 文件。这个基础开发的参数
执行生成
插件安装好后,在项目的任意目录或文件上右键,选择 ScreenMatch 选项。如下图:
然后选择在哪个 module 下执行适配。即基于哪个 module 下的 res/values/dimens.xml 文件作为基准 dimens.xml 文件,生成的其他尺寸 dimens.xml 文件放在哪个 module 下。例如选择 app,然后点击 OK ,出现如下界面表示生成文件成功。如下图:
然后再看看 res 目录下会自动生成一堆 dimens.xml 文件,如下图:
通过上面的步骤就已经生成了所有设备对应的 dimens.xml 文件。
生成原理
根据设计图填写最小宽度基准值,并填写需要适配的设备最小宽度 dp 值
步骤 3 是以插件默认的最小宽度基准值为 360dp,适配的设备最小宽度为320,360,384,392.7272,400,410,411.4285,432,480,533,592,600,640,662,720,768,800,811,820,960,961,1024,1280,1365(包含了平板和 TV )生成的文件,但实际情况要根据设计图和需求设置。
例如设计图的最小宽度为 375dp,则需要更改最小宽度基准值为 375dp。如果项目只需要适配手机的话,适配的设备最小宽度保留 320,360,384,392.7272,400,410,411.4285,432,480 即可,若发现手机还有其他最小宽度自行加上即可。
以上修改需要在配置文件里修改,即 screenMatch.properties 文件,该配置文件是执行完上面第 3 步后自动生成在项目的跟目录下的。如下图:
如何修改适配参数?
打开配置文件,修改下图中 1、3、4 的值即可。(图中单位均为 dp)
1:最小宽度基准值,填写设计图的最小宽度值即可。
2:插件默认适配的最小宽度值,即默认情况下会生成如下值的 dimens.xml 文件。
3:需要适配的最小宽度值(如果是小数,则保留 4 位小数。例如 392.727272…,则取 392.7272),即你想生成哪些 dimens.xml 文件。
4:忽略不需要适配的最小宽度值,即忽略掉插件默认生成的 dimens.xml 文件。
配置文件修改完成后,重新执行第 3 步,生成新的 dimens.xml 文件。
三 代码改造
改造背景一:知道当前代码基准值base_dp,代码之前写的是用px,怎么转化成dp?
首先代码中如果有px怎么该宽度下的dp。如下了解android原生转换背景
密度类型 代表的分辨率(px) 屏幕密度(dpi) 换算(px/dp) 比例
低密度(ldpi) 240x320 120 1dp=0.75px 3
中密度(mdpi) 320x480 160 1dp=1px 4
高密度(hdpi) 480x800 240 1dp=1.5px 6
超高密度(xhdpi) 720x1280 320 1dp=2px 8
超超高密度(xxhdpi) 1080x1920 480 1dp=3px 12
在Android中,规定以160dpi(即屏幕分辨率为320x480)为基准:1dp=1px。
同理:得出某像素密度ppi下,像素px和dp的转化关系
dp = px / (ppi / 160)
举例:知道屏幕像素是2560x1440,屏幕密度187,长宽度:2190x1232单位dp,最小宽度限定符用的是最小值。即1232。
原本代码开发完成后图片像素为400px,为了适配该方案需要转换dp。转换结果400/(187/160