dp与px转换原理
更多面试题请看这里:https://interview.raoyunsoft.com/
面试题专栏会持续更新欢迎关注订阅
在Android开发中,dp(密度无关像素)和px(物理像素)的转换是屏幕适配的核心基础。理解它们的转换机制能有效解决多设备适配问题。
▎dp转px实现方案
通过获取设备屏幕密度比例进行换算:
public static int dpToPx(Context context, float dpValue) { // 获取屏幕密度比例(1dp = 1px in mdpi) float scale = context.getResources().getDisplayMetrics().density; // 添加0.5f实现四舍五入取整 return (int) (dpValue * scale + 0.5f);
}
关键解析:
density值含义:- 1.0:mdpi(160dpi)基准密度
- 1.5:hdpi
- 2.0:xhdpi
- 3.0:xxhdpi
+0.5f作用:避免float转int时的截断误差,实现精确四舍五入
▎px转dp实现方案
逆向换算时需要反向应用密度比例:
public static int pxToDp(Context context, float pxValue) { float scale = context.getResources().getDisplayMetrics().density; // 反向除法计算 + 四舍五入 return (int) (pxValue / scale + 0.5f);
}
▎现代开发最佳实践
1. 使用扩展函数(Kotlin)
fun Context.dpToPx(dp: Float): Int = (dp * resources.displayMetrics.density + 0.5f).toInt() fun Context.pxToDp(px: Float): Int = (px / resources.displayMetrics.density + 0.5f).toInt()
2. Compose中的单位处理
Jetpack Compose已内置dp自动转换:
@Composable
fun TextComponent() { Text( text = "自适应文本", modifier = Modifier.padding(16.dp) // 无需手动转换 )
}
▎适配陷阱规避
- 不要缓存density值:
屏幕方向切换时displayMetrics可能变化 - 避免硬编码转换:
// 错误做法 ❌ int px = (int)(dp * 2 + 0.5); - 折叠屏特殊处理:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { val density = context.display?.density ?: resources.displayMetrics.density }
关键记忆点:所有View的最终渲染单位都是px,系统在measure/layout阶段自动完成dp->px转换,自定义View时需手动处理。
