dp, sp, px 与 Android 界面布局自适应

更新日期: 2023-11-14 阅读次数: 537 字数: 789 分类: Android

之前写 Android 平板 App,由于没有正经写过 Android 界面布局,为了图省事, 直接用 px 像素做的布局,及字号大小设置。

好在平板是我们指定的型号,屏幕尺寸,及像素。但是自从发货到客户手中之后, 我就非常担心,一旦这款平板停产,换个更高分辨率的平板怎么办?

为了消除焦虑,我了解了一下 Android 布局的基础。

总结起来一句话:

字号用 sp,宽高用 dp。

问题简化

  • 图片宽度用什么单位? dp
  • 字号用什么单位?sp
  • dp 是什么?
  • dp 是怎么换算为 px 的?

dp 是怎么换算为 px 的

android 中,dp 在渲染前,都会被转换成 px。

px = density * dp

density 密度

density 即,密度的意思。

Android kotlin 获取 density (float 类型):

val density = resources.displayMetrics.density

例如,在我当前使用的华为平板中,density 值为 1.75; 小米手机为 2.75。

获取 Android 设备的屏幕信息,即宽度对应的 dp

比如在 main activity 中定义一个获取屏幕信息的 kotlin 函数:

private fun getScreenInfo(context: Context) {
	val displayMetrics = resources.displayMetrics

	val screenWidthInPx = displayMetrics.widthPixels
	val density = displayMetrics.density
	val dpi = displayMetrics.densityDpi
	val screenWidthInDp = (screenWidthInPx / density).toInt()

	// 台电平板:screenWidthInPx: 1920, density: 1.75, screenWidthInDp: 1097, dpi: 280
    // 华为平板:screenWidthInPx: 2000, density: 2.0, screenWidthInDp: 1000, dpi: 320
	println("screenWidthInPx: $screenWidthInPx, density: $density, screenWidthInDp: $screenWidthInDp, dpi: $dpi")
}

然后在 onCreate 中调用:

getScreenInfo(this)

根据输出的 screenWidthInDp: 1097。

可以将蓝湖/codesign 这类设计工具中的宽度变更为 1097,以自动转换界面元素的大小。

手里两个平板,一个华为,一个台电,上面4个参数都完全一样。

而我的小米手机在竖屏/横屏不同状态下,返回的 screenWidthInDp 是不一样的。

screenWidthInPx: 1080, density: 2.75, screenWidthInDp: 392, dpi: 440
screenWidthInPx: 2270, density: 2.75, screenWidthInDp: 825, dpi: 440

看起来手机上的 screenWidthInDp 比平板的要小。所以如果要兼容手机,布局上还是要灵活一点。

DPI 与 PPI

  • DPI(Dots Per Inch,每英寸点数, 一英寸等于2.54厘米)
  • PPI(Pixels Per Inch,每英寸像素密度)

PPI(Pixels Per Inch)则是一个描述屏幕像素密度的度量单位。 它指的是在每英寸线性距离上的像素数量。 PPI 的概念主要应用于显示设备,用于表示屏幕上每英寸的像素数量。 PPI 值越高,屏幕显示的图像就越细腻和清晰。

不同 dp 宽度屏幕的兼容性/自适应问题

虽然很多 android 平板,看上去是都是 10.1 寸屏,但是实际上有的屏幕像素密度很低,比如 Android 工控屏。 这时,其 dp 为单位的宽度,就比正常的平板,要大一些。就会导致布局看起来跟预想的不一样。

还是需要一些布局的基本原则的:

  • 考虑清楚那部分应该是居中的
  • 不要使用上下左右边距,即 margin,来布局边界元素。尽量使用居中排版
  • 考虑 max,min 各种尺寸的屏幕,其 dp 大概有多大。做类似于 web 那样的布局方案

英寸与英尺

  • 一英寸等于 2.54 厘米
  • 一英尺等于 30.48 厘米

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式