android - DisplayMetrics.scaledDensity 在 Android 中实际返回什么?

标签 android

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

sp

Scale-independent Pixels - This is like the dp unit, but it is also scaled by the user's font size preference. It is recommend you use this unit when specifying font sizes, so they will be adjusted for both the screen density and the user's preference.

使用 DisplayMetrics有可能得到 scaledDensity这是:

A scaling factor for fonts displayed on the display. This is the same as density, except that it may be adjusted in smaller increments at runtime based on a user preference for the font size.

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

但是,当我在手机 (Nexus 4) 上测试时,我没有得到预期的结果。 DisplayMetrics.scaledDensity 始终返回相同的值(等于 DisplayMetrics.density),无论我将手机设置为使用什么字体大小(通过 settings -> accessibility -> use large fontsettings -> 显示 -> 字体大小).

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

我用来获取 scaledDensity 的代码是:

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

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

更新

下面是三个截图来说明我的意思:

enter image description here

这是应用程序的代码:

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 源代码后,我 found scaledDensity 属性计算为 scaledDensity = density * fontScale 其中 fontScale取决于字体大小的系统设置。所以这就像我认为的那样。

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

Returns the Display upon which this WindowManager instance will create new windows.

Despite the name of this method, the display that is returned is not necessarily the primary display of the system (see DEFAULT_DISPLAY). The returned display could instead be a secondary display that this window manager instance is managing. Think of it as the display that this WindowManager instance uses by default.

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

通过使用 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);

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

enter image description here

关于android - DisplayMetrics.scaledDensity 在 Android 中实际返回什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22916490/

相关文章:

android - 如何使用套接字在域中找到所有其他IP地址

php - 从服务器下载一堆文件

Android 应用发布 - "No devices supported"

java - 改造错误 URL 查询字符串不能有替换 block

java - 如何通过 Android Intent 发送 Parse objectId?

Android USSD 哪个 sim 卡收到 ussd 消息或哪个 sim 插槽收到 ussd 消息(双卡手机)

java - Android:ListView 中 getCount() 和 getChildCount() 之间的区别

android - 使用改造上传文件时出现错误(没有这样的文件或目录)

android - 设置android :installLocation ="preferExternal"时出错

android - Activity 之间的通信 : Intent or Service: what is faster?