【问题标题】:What does DisplayMetrics.scaledDensity actually return in Android?DisplayMetrics.scaledDensity 在 Android 中实际返回什么?
【发布时间】:2014-04-15 20:13:17
【问题描述】:

我试图了解 Android 中的 sp 单元,但我无法真正弄清楚它是如何工作的。 documentation 说:

sp

Scale-independent Pixels - 这就像 dp 单位,但它也是 按用户的字体大小偏好缩放。建议您使用 这个单位在指定字体大小时,因此它们将被调整为 屏幕密度和用户偏好。

使用DisplayMetrics 可以获得scaledDensity,即:

显示器上显示的字体的比例因子。这是一样的 作为密度,除了它可以在较小的增量调整 运行时基于用户对字体大小的偏好。

因此,鉴于此信息,我假设 scaledDensity 会随着我更改系统字体大小而改变,并且我可以使用此信息来了解 1dp 和 1sp 之间的比率 (scaledDensity / density)。

但是,当我在手机 (Nexus 4) 上对此进行测试时,我没有得到预期的结果。无论我将手机设置为哪种字体大小(通过settings -> accessibility -> use large fontsettings -> display -> font size),DisplayMetrics.scaledDensity 始终返回相同的值(等于 DisplayMetrics.density)。

当我更改字体设置时,我的 sp 指定的字体会更改大小,因此 sp 单元按预期工作,但 scaledDensity 值根本不会改变。

我用来获取 scaledDensity 的代码是:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
metrics.scaledDensity

我是做错了什么还是我误解了 DisplayMetrics.scaledDensity 的实际作用?

更新

这里有三个屏幕截图来说明我的意思:

这是应用程序的代码:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

String result = "\n"
    + "density : " + metrics.density + " (24 dp = " + 24 * metrics.density + " px)\n"
    + "scaledDensity: " + metrics.scaledDensity + " (24 sp = " + 24 * metrics.scaledDensity + " px)\n";

((TextView) this.findViewById(R.id. label)).setText(result);
((TextView) this.findViewById(R.id. sp)).setTextSize(android.util.TypedValue. COMPLEX_UNIT_SP , 24);
((TextView) this.findViewById(R.id.dp )).setTextSize(android.util.TypedValue. COMPLEX_UNIT_DIP, 24);

我希望能够计算 y 方向绘制某个字符串所需的像素数量。如果我使用 dp 指定字符串的大小,我可以使用displayMetrics.density 轻松计算所需的像素。但是当我使用 sp 并尝试使用 displayMetrics.scaledDensity 计算像素数量时,我没有得到正确的值。

【问题讨论】:

    标签: android


    【解决方案1】:

    我自己能够弄清楚这一点。在挖掘 Android 源代码后,我 found 发现 scaledDensity 属性计算为 scaledDensity = density * fontScale 其中 fontScale 取决于字体大小的系统设置。所以这就是我想的那样。

    scaledDensity 无论字体大小对我来说总是具有相同的值的原因是我将 DisplayMetrics 用于错误的显示。我从默认显示中获得了 DisplayMetrics,对此documentation 说:

    返回此 WindowManager 实例将在其上创建新窗口的 Display。

    尽管有此方法的名称,但返回的显示不一定是系统的主显示(请参阅 DEFAULT_DISPLAY)。返回的显示可能是此窗口管理器实例正在管理的辅助显示。将其视为此 WindowManager 实例默认使用的显示器。

    在这种情况下,默认显示与系统的主显示不同,因此当我更改系统字体设置时,该设置在主显示上更改,而不是在默认显示上。如果我更新我的代码以获取实际使用的显示器的DisplayMetricsscaledDensity 返回根据系统字体设置缩放的预期值。

    使用以下使用getResources().getDisplayMetrics() 的更新代码,一切都按预期工作:

    DisplayMetrics metrics = getResources().getDisplayMetrics();
    String result = "\n"
        + "density : " + metrics.density + " (24 dp = " + 24 * metrics.density + " px)\n"
        + "scaledDensity: " + metrics.scaledDensity + " (24 sp = " + 24 * metrics.scaledDensity + " px)\n" ;
    
    ((TextView) this.findViewById(R.id.label)).setText(result);
    ((TextView) this.findViewById(R.id.sp)).setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
    ((TextView) this.findViewById(R.id.dp)).setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24);
    

    通过这种获取显示指标的方式,这是我得到的结果(观察缩放密度如何随字体大小变化):

    【讨论】:

      【解决方案2】:

      缩放密度是一种度量单位,而不是字体大小的值。让我试着给你一个例子,如果你想要更多的解释,请随时发表评论。

      假设您的字体大小为 18sp。这需要转换为像素才能显示在屏幕上。进行以下计算:pixels = fontSize * scaledDensity * scale。现在,当您更改手机设置时,您正在更改比例。这导致进行相同的计算,但假设现在使用 1.5 而不是 1 的比例。scaledDensity 的单位没有改变,因为您的屏幕的像素密度没有改变。

      希望对你有帮助!

      【讨论】:

      • 我不确定我是否理解。在我的应用程序中,我将 TextView 的字体大小设置为 12sp,并将系统字体大小设置为“正常”。由于在这种情况下 scaledDensity 返回 2.0,我假设绘制此文本所需的像素数量为 12 * 2.0 = 24。然后我进入系统设置并将字体大小更改为巨大。当我重新启动我的应用程序时,我可以看到 TextView 中的文本在屏幕上绘制得更大,即使 TextView 的字体大小仍设置为 12sp。所以在这里我预计 scaledDensity 值会增加以考虑绘制的大量像素。
      • 此外,scaledDensity 的文档说:“这与密度相同,只是它可以在运行时根据用户对字体大小的偏好以较小的增量进行调整 。”所以即使屏幕的像素密度不变,它也应该能够改变。
      • 看起来我在使用 sp 时在计算字体大小时遗漏了一个因素。看看我的编辑。
      • 感谢您的更新,但为什么文档说 scaledDensity 可能会在运行时根据用户对字体大小的偏好进行更改?如果 scaledDensity 只取决于屏幕的像素密度,那么 scaledDensity 和 density 有什么区别?
      • 我正在根据屏幕尺寸缩放图像(通过对 height/ydpi 和 width/xdpi 的平方和求平方根来计算)并得到不一致。当我考虑到 scaledDensity 时,一切都变得一致了。所以它不仅仅是文本。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多