首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android UI 开发里的尺寸单位理解

Android UI 开发里的尺寸单位理解

作者头像
mzlogin
发布2020-04-16 15:30:24
1.2K0
发布2020-04-16 15:30:24
举报
文章被收录于专栏:闷骚的程序员闷骚的程序员

在学习 Android UI 开发的初期,经常被一些常用概念如 dp、sp 和它们与 px 的换算等虐,要避免被虐,最好的方法当然是知其所以然,再见到它们就胸中有料心不慌了。

背景知识

参考 http://developer.android.com/guide/practices/screens_support.html#terms

  1. 屏幕大小(Screen size) 屏幕对角线的实际物理大小。通常以英寸(inch)为单位。
  2. 屏幕密度(Screen density) 每英寸上的像素个数。通常被称作多少 dpi(dots per inch)或多少 ppi(pixels per inch)。 比如,LG Nexus 5 的屏幕尺寸为 4.95 英寸,分辨率为 1920*1080,则它的对角线上的像素数为 sqrt((sqr(1920)+sqr(1080)),所以它的屏幕密度为 sqrt((sqr(1920)+sqr(1080))/4.95=445.03,约为 445dpi。
  3. 分辨率(Resolution) 屏幕上的物理像素个数。 比如 LG Nexus 5 的分辨率为 1920*1080,这里的 1920 和 1080 就是屏幕长和宽上的像素个数。

尺寸

参考 http://developer.android.com/guide/topics/resources/more-resources.html#Dimension

  1. dp(Density-independent Pixels) 在不同大小、密度和分辨率的屏幕上的物理大小都近似相等的虚拟尺寸单位。 约为 1/160 英寸(为什么是约为?稍后讲解)。
  2. sp(Scale-independent Pixels) 基于首选字体大小的缩放像素。 与 dp 类似,但是会根据用户的首选字体大小缩放。
  3. pt(Points) 1/72 英寸。
  4. px(Pixels) 像素。
  5. mm(Millimeters) 毫米。
  6. in(Inches) 英寸,约 2.539999918 厘米。

换算

dp 转 px

参考http://developer.android.com/guide/practices/screens_support.html#dips-pels

为了简单起见,Android 将屏幕密度概括为 6 种:

  • ldpi(low) ~120dpi
  • mdpi(medium) ~160dpi
  • hdpi(high) ~240dpi
  • xhdpi(extra-high) ~320dpi
  • xxhdpi(extra-extra-high) ~480dpi
  • xxxhdpi(extra-extra-extra-high) ~640dpi

但是并非表示所有 Android 手机只有这几个屏幕密度,比如上面举例的 LG Nexus 5 的屏幕密度是 445dpi,近似地归于 xxhdpi,Android 在内部进行 dp 到 px 的换算时将采用 480dpi 而非 445dpi

简而言之,dp 数 x 换算成 px 数 y 的公式:

// 向上取整
y = x * generalizedDensity / 160

这里的 generalizedDensity 就是以上 6 种中的一个值,比如 LG Nexus 5 的实际屏幕密度为 445dpi,但是归于 xxhdpi,所以它的 generalizedDensity 就是 480dpi。

官方文档给出的转换 dp 到 px 的代码示例为:

// The gesture threshold expressed in dp
private static final float GESTURE_THRESHOLD_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
mGestureThreshold = (int) (GESTURE_THRESHOLD_DP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels...

在 mdpi(160dpi)上 1dp=1px(还记得前面讲过的 1dp 约为 1/160 英寸吗?在 160dpi 的屏幕上,1px=1/160 英寸),这里的getResources().getDisplayMetrics().density实际上就等于我们的generalizedDensity / 160,表示将 dp 转换为 px 的一个转换因子。

然后来理解一下为何 dp 是约为 1/160 英寸。

还是以 LG Nexus 5 举例,比如 160dp,若在一个屏幕密度恰好是 480dpi 的机器上,那它会是准确的 1 英寸,但是 LG Nexus 5 的屏幕密度是 445dpi,根据上面的公式计算得出:160dp = 160 * 480 / 160 px = 480px,则它的实际显示尺寸为 480/445=1.07865 英寸。所以原因是dp 换算成 px 是使用 Android 概括的六种屏幕密度之一,而非实际屏幕密度,所以在不同的手机上相同数量的 dp 显示尺寸会有轻微差异。

sp 转 px

http://developer.android.com/reference/android/util/DisplayMetrics.html#scaledDensity中可以看到scaledDensity就是控制字体尺寸的缩放因子。于是猜想 sp 数 x 换算成 px 数 y 的公式:

y = x * scaledDensity

这里的 scaledDensity 获取方式为getResources().getDisplayMetrics().scaledDensity

这个猜想是否正确呢?看看下面一张图就明白啦!(Nexus 4 模拟器截图)

font-size
font-size

根据分辨率和屏幕密度求屏幕尺寸

使用 adb 命令 adb shell wm size 可以得到设备分辨率,adb shell wm density 可以得到设备屏幕密度,但貌似没有办法直接得到屏幕尺寸,只能拿到这两个数据之后换算。

公式:

sqrt(sqr(width)+sqr(height))/density
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015/04/06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景知识
  • 尺寸
  • 换算
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档