一文搞懂Android中dp、sp与px的关系!

1.屏幕基础

先了解屏幕相关的基础概念:

  1. 屏幕尺寸屏幕对角线的实际物理尺寸。单位英寸(inch) ,1英寸 = 2.54厘米
  1. 屏幕像素数屏幕上水平和垂直方向上的像素点总数。通常以宽度(K)×高度(P)的形式表示,例如1920×1080 - 1080P, 2048 * 1080 - 2K , 4096×1080 - 4K。 平常说的 1080P 指的是高度占据1080个物理像素,而 2K 或者4K 指的是宽度占据一定数量的像素数,K表示等效像素,1个等效像素 = 1024个物理像素,一换算就出来了。

  2. 屏幕分辨率即屏幕密度, 单位dpi(dots per inch ,每英寸点数)或者ppi (pixels per inch ,每英寸像素数) ,两者一般等效,屏幕的清晰程度取决于屏幕分辨率,屏幕分辨率越高,每英寸展示的像素数越多,图像就越精细,而非唬人的像素数(什么2k、4k等)。

2.屏幕单位

  1. px物理像素,对应屏幕上的实际物理像素点。

  2. destiny屏幕密度,单位 dpi (dots per inch ,每英寸点数),注意和ppi (pixels per inch ,每英寸像素数) 区分,据网上资料显示,在屏幕显示领域,这两个值可以互换使用。即屏幕密度代表每英寸点数或者像素数!该值主要影响图像的显示精细度或者质量,因为每英寸的点数或者像素数越多,图像就越精细。 该值代表了屏幕的清晰度。

  3. dip(dp)密度无关像素,全称 densiny-independent pixels,这是Android系统中专门为了避免直接使用 px(物理像素)而造成的图像大小不同的情况。该值定义为等于屏幕密度为 160 dpi 的屏幕上的一个物理像素,系统会在运行时根据具体的屏幕密度对dp的大小进行缩放处理,因为不管是 dp 或者 sp 最终都会转换成 px。

  4. sp放大像素(比例像素) 全称 scaled pixels-best for text size,同为Android系统中专用单位,和 dp 单位一般情况下相同,但可以根据用户配置的字体大小进行缩放。 用于字体的大小,切勿用于布局。

3.换算关系

1.由于 1 dp(密度无关像素) 定义为屏幕密度为 160 dpi 屏幕上的一个px(物理像素)

=> 我们可以得出基准屏幕密度为 160dpi = 160 ppi = 160 像素数/英寸 或者 点数/英寸

=> px = dp * (destiny / 160)

例如,一个屏幕密度为320dpi 的设备上,1dp等于多少实际的物理像素?

代入上述公式可得 1 * (320/160) = 2px,可以看出1dp 等于2px。

2.那在不同屏幕密度的手机屏幕上,相同的 dp 是否会造成不同的显示大小呢?

继续换算下,屏幕密度为160dpi的屏幕上,每个像素大小为 1/160 英寸, 1dp = 1px => 1/160 英寸,即1dp 对应1/160英寸。

当屏幕密度变为320dpi 时,每个像素大小为1/320英寸,1dp = 2px => 2 * 1/320 = 1/160 英寸,1dp 仍然对应1/160英寸。

所以相同 dp 在不同 destiny 的手机上, 仍然保持同样的大小,即dp/sp 屏蔽了不同屏幕密度设备上视图大小的差异。 如下图:

4.Android 设备中的 dp 与 sp

回到安卓手机中,设备不仅具有不同的屏幕尺寸(手机、平板电脑、电视等),而且具有不同像素尺寸的屏幕。一台设备的每英寸像素数可能为 160,而另一台设备在同一空间内可以容纳 480 像素。如果不考虑像素密度的这些变化,系统可能会缩放图片,导致图片模糊不清,或者图片可能以错误的尺寸显示。因此出现了dp和sp,屏蔽掉设备屏幕密度的差异。

可以看到,相同屏幕尺寸的手机,不同屏幕密度,通过使用密度无关像素(dp)展示的图片具有相同大小!

在 Android 设备中,通过 DisplayMetrics 度量系统获得的 destiny 实际上是设备的逻辑屏幕密度 ,该值为设备实际屏幕密度/160 ,我的手机输出的 DisplayMetrics.destiny 为3.0 (设备实际的屏幕密度 / 160),是超超高密度屏幕~

  • 在低密度屏幕上,DisplayMetrics.density等于 0.75;
  • 在中密度屏幕上, DisplayMetrics.density等于 1.0;
  • 在高密度屏幕上, DisplayMetrics.density等于 1.5;
  • 在超高密度屏幕上,DisplayMetrics.density等于 2.0
php 复制代码
    /**
     * The logical density of the display.  This is a scaling factor for the
     * Density Independent Pixel unit, where one DIP is one pixel on an
     * approximately 160 dpi screen (for example a 240x320, 1.5"x2" screen), 
     * providing the baseline of the system's display. Thus on a 160dpi screen 
     * this density value will be 1; on a 120 dpi screen it would be .75; etc.
     *  
     * <p>This value does not exactly follow the real screen size (as given by 
     * {@link #xdpi} and {@link #ydpi}, but rather is used to scale the size of
     * the overall UI in steps based on gross changes in the display dpi.  For 
     * example, a 240x320 screen will have a density of 1 even if its width is 
     * 1.8", 1.3", etc. However, if the screen resolution is increased to 
     * 320x480 but the screen size remained 1.5"x2" then the density would be 
     * increased (probably to 1.5).
     *
     * @see #DENSITY_DEFAULT
     */
    public float density;

1.在 Android 中,设备的 dp 和 sp 与 px 的换算关系?

DisplayMetrics.density 代表设备的逻辑屏幕密度 ,而 DisplayMetrics.scaledDensity 代表设备字体逻辑缩放因子

一般情况下 scaledDestiny = destiny ,但保不好用户会进行调整字体大小或者显示大小,导致scaledDestiny > destiny 或者 scaledDestiny < destiny,因此字体会按照scaledDestiny进行缩放。

dp 和 px换算关系: px = dp * DisplayMetrics.density

sp 和 px换算关系: px = sp * DisplayMetrics.scaledDensity

dp 和 sp 换算关系:dp:sp = DisplayMetrics.scaledDensity: DisplayMetrics.density

2.如下图,如果更改系统字体大小后,想保持应用的字体不变怎么办?

系统字体大小只影响 scaledDestiny,不影响 destiny。

可以在 sp 转 dp 时,不使用 DisplayMetrics.scaledDestiny,而是自定义转换,比如使用DisplayMetrics.destiny;或者干脆直接使用 dp 的单位。

3.如下图,如果更改系统显示大小后,想保持应用的字体不变怎么办?

系统显示大小不只影响 scaledDestiny,还影响 destiny。后面会专门再出一篇讲解~

相关推荐
千里马学框架7 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台8 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone8 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc9 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo10 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun00770011 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼11 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone12 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen12 小时前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone12 小时前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui