Android 屏幕适配

1,088 阅读3分钟

1、查看屏幕信息

1.1、通过adb指令

# 查看屏幕分辨率
adb shell wm size

# 设置屏幕分辨率为 1920x1080
adb shell wm size 1920x1080

# 重置屏幕分辨率
adb shell wm size reset
# 查看屏幕密度
adb shell wm density

# 设置屏幕密度为 160
adb shell wm density 160

# 重置屏幕密度
adb shell wm density reset

image.png

1.2、通过代码方式

Android提供了 DisplayMetrics 类,包含与屏幕相关的参数,可以通过屏幕的 DisplayMetrics 对象获取参数 widthPixels:屏幕宽度,单位px; heightPixels:屏幕高度,单位px; densityDpi:屏幕密度,对角线每英寸的像素数; density:屏幕密度比值,densityDpi/160;

fun getScreenMetrics(context: Context) {
    val metrics = context.resources.displayMetrics
    val density = metrics.density
    val dpi = metrics.densityDpi
    val widthPixels = metrics.widthPixels
    val heightPixels = metrics.heightPixels
    val scaleDensity = metrics.scaledDensity
}

// density: 1.0
// dpi: 160
// widthPixels: 1920
// heightPixels: 1080

2、android res 中 values-swxxdp 计算方式

最小宽度计算公式:

sw = 160 * 宽度像素 / 屏幕密度(dpi)

eg: sw = 160 * 1920 / 160 = 1920 res 资源目录下配置values-sw1920dp即对应该屏幕的尺寸资源;

配置文件读取规则是最接近但不超过,如果有两个 values-sw1900dp 和 values-sw1930dp, sw 是1920,优先读取 sw1920 配置,如果没有则读取 sw1900 配置。

  • 160 是基准屏幕密度

dp 能够让同一数值在不同的分辨率展示出大致相同的尺寸大小,但是当设备的尺寸差异较大时,我们需要按照sw进行适配不同屏幕尺寸的配置文件,已达到预期效果;

3、基本知识

3.1、基本概念

  • dpi:屏幕密度,指对角线方向1英寸长度包含的像素数量,基准屏幕密度为160(即对角线方向1英寸内包含160个像素);
  • density:屏幕密度比值,当前屏幕密度与基准屏幕密度(160dpi)的比值;
  • px:像素(Pixel),屏幕显示的基本单位,px代表一个像素的长度;
  • dp:独立像素密度(Density-independent pixel),android特有定义,类似于物理长度单位,与像素密度无关,1dp相当于对角线方向1英寸的1/160;
  • sp:与dp相似,主要用于字体尺寸,跟随系统字体大小进行缩放;

3.2、单位转换

# dpi与density转换:
dpi = density * 160

# px与density转换
px = dp * density = dp * (dpi / 160)

dp与px转换
dp = px / (dpi / 160) = px / density
px = dp * (dpi / 160) = dp * density

sp与px
sp = px / (dpi / 160) = px / density
px = sp * (dpi / 160) = sp * density

3.3、代码转换


// 获取当前屏幕密度比值
fun density(): Float {
    return Resources.getSystem().displayMetrics.density
}

// dp转px,扩展属性方式
Int.dp2px: Int
    get() {
        val density = density()
        return (this * density + 0.5f).toInt()
    }

// px转dp,扩展属性方式
Int.px2dp: Int
    get() {
        val density = density()
        return (this / density + 0.5f).toInt()
    }

// sp转px,扩展属性方式
Int.sp2px: Int
    get() {
        val density = density()
        return (this * density + 0.5f).toInt()
    }

// px转sp,扩展属性方式
Int.px2sp: Int
    get() {
        val density = density()
        return (this / density + 0.5f).toInt()
    }

4、配置文件生成

转换公式:

目标宽度 = 预期屏幕宽度*1.0f / 基准屏幕宽度

目标高度 = 预期屏幕高度*1.0f / 基准屏幕高度

配置文件生成工具参考连接