Android 中常见的屏幕密度分类有哪些?对应的 dp 到 px 换算比例是多少?

解读

面试官问这道题,并不是想听你把六个密度值背一遍,而是考察三条线:

  1. 你是否真在项目中处理过“图标糊了”“按钮大了”这类视觉问题;
  2. 你是否理解 dp 存在的根本原因——屏蔽不同物理 ppi 带来的尺寸漂移;
  3. 你是否能把“密度桶”与“资源目录 drawable-、values-、dimens.xml”对应起来,讲出实际适配套路。
    答得太浅(只背 ldpi~xxxhdpi)会被认为没踩过坑;答得太深(把工厂校准 γ 值、ppi 计算公式全甩出来)又显得过度。国内面试场景最吃香的答法是:先给出官方六档,再补一个“360dp 宽”设计基准,最后落到“换算比例 + 资源目录 + 实战踩坑”三位一体。

知识点

  1. 官方六档密度桶:ldpi、mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi,对应 dpi 区间 120、160、240、320、480、640。
  2. dp 定义:160 dpi 为基准,1 dp = 1 px;其余密度按 px = dp × (dpi / 160) 线性缩放。
  3. 国内主流机型集中在 xhdpi(320 dpi)与 xxhdpi(480 dpi),折叠屏外屏往往 360420 dpi 仍被系统归到 xhdpi,内屏 480560 dpi 归到 xxhdpi,面试时把“归桶规则”点出来是加分项。
  4. 资源匹配顺序:系统先找精确密度桶,再向上就近取大,再向下取小;若只有 xxxhdpi 图标,低内存机可能被自动降采样,导致 OOM 或模糊,需要放多份素材或改用矢量。
  5. 设计稿常用 360 dp 宽基准:360 dp × 2 = 720 px 对应 xhdpi,360 dp × 3 = 1080 px 对应 xxhdpi,与主流 1080P 屏整数倍,开发可直接写 1:2、1:3 比例,减少浮点误差。
  6. 代码获取比例:context.getResources().getDisplayMetrics().density,返回 2.0 即 xhdpi,3.0 即 xxhdpi,面试时把“运行时读 density”说出来,能证明你写过适配工具类。

答案

Android 官方把屏幕密度分成六档:
ldpi(约 120 dpi)、mdpi(160 dpi)、hdpi(240 dpi)、xhdpi(320 dpi)、xxhdpi(480 dpi)、xxxhdpi(640 dpi)。
dp 到 px 的换算比例以 160 dpi 为基准 1×,其余依次为 0.75×、1×、1.5×、2×、3×、4×。
换算公式:px = dp × (dpi / 160),代码中可直接使用 TypedValue.applyDimension 或 displayMetrics.density 完成转换。
国内线上用户 90% 以上集中在 xhdpi 与 xxhdpi,因此设计稿常以 360 dp 宽为基准,输出 720 px(xhdpi)与 1080 px(xxhdpi)两套素材即可覆盖主流机型;更高密度桶只需补图标即可,普通切图可交由矢量 drawable 或.9 图自动拉伸。

拓展思考

  1. 折叠屏与平板新密度:华为 Mate X3 外屏 426 dpi 被系统归到 xhdpi,内屏 480 dpi 归到 xxhdpi,但物理尺寸差异大,需额外考虑 sw600dp 与 sw720dp 限定符,而不是单纯看密度桶。
  2. 字体缩放独立:sp 与 dp 比例相同,但用户可在系统设置里放大字体,面试可补充“布局高度不用 sp,字体大小用 sp,并通过 autosizeTextType 做动态压缩”。
  3. 低端机降采样:Android 8 以后对内存紧张设备会自动降级到更低密度桶,导致 xxxhdpi 图标被系统丢弃,若应用只有一份高清素材,图标反而消失;解法是在 build.gradle 中配置 resConfigs "zh", "xxhdpi" 或使用 vectorDrawable。
  4. 动态换算工具:今日头条方案通过修改 DisplayMetrics.density 实现“全局 1 dp = 1 px”的强制等比缩放,面试提到此方案时需指出它破坏系统缓存、导致 Dialog 尺寸异常,官方并不推荐,但在国内插件化与热修复场景下仍有公司使用。