之前写 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 聊聊, 查看更多联系方式