DisplayMetrics.scaledDensity在Android中实际返回什么? [英] What does DisplayMetrics.scaledDensity actually return in Android?

查看:395
本文介绍了DisplayMetrics.scaledDensity在Android中实际返回什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解Android中的sp单元,但是我真的无法弄清楚它是如何工作的.,将 scaledDensity 属性计算为 scaledDensity = density * fontScale ,其中文档a>说:

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

尽管使用了该方法的名称,但返回的显示不一定是系统的主要显示(请参阅DEFAULT_DISPLAY).取而代之的是,返回的显示可以是此窗口管理器实例正在管理的辅助显示.可以将其视为此WindowManager实例默认使用的显示.

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

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

  DisplayMetrics指标= getResources().getDisplayMetrics();字符串结果="\ n"+密度:" + 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); 

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

I'm trying to understand the sp unit in Android, but I can't really figure out how it works. The documentation say:

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.

Using DisplayMetrics it is possible to get the scaledDensity which is:

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.

So given this information I assume that the scaledDensity will change as I change the system font size and that I can use this information to know the ratio between 1dp and 1sp (scaledDensity / density).

However when I'm testing this on my phone (Nexus 4) I am not getting the results I'm expecting. DisplayMetrics.scaledDensity always returns the same value (equal to DisplayMetrics.density) regardless of what font size I have set my phone to use (via settings -> accessibility -> use large font or settings -> display -> font size).

When I change the font settings my sp specified fonts changes size, so the sp unit works as expected but the scaledDensity value doesn't change at all.

The code I'm using to get the scaledDensity is:

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

Am I doing something wrong or have I misunderstood what DisplayMetrics.scaledDensity actually does?

Update

Here are three screenshots that illustrates what I mean:

And this is the code for the application:

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);

I want to be able to calculate the amount of pixels needed y-wise to draw a certain string. If I specify the size of the string using dp I can easily calculate the required pixels using displayMetrics.density. But when I use sp and try to calculate the amount of pixels using displayMetrics.scaledDensity I do not get the correct values.

解决方案

I was able to figure out this myself. After digging trough the Android source code I found that the scaledDensity property is calculated as scaledDensity = density * fontScale where fontScale depends on the system setting for font size. So this was just as I thought it should be.

The reason why scaledDensity always had the same value for me regardless of font size was because I was using the DisplayMetrics for the wrong Display. I got the DisplayMetrics from the default display and regarding this the documentation say:

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.

In this case the default display is not the same display as the primary display of the system, so when I change the system font setting that setting is changed on the primary display and not on the default display. If I update my code to get the DisplayMetrics for the display that is actually used scaledDensity returns the expected values scaled according to the system font settings.

With the following updated code that uses getResources().getDisplayMetrics() everything works as expected:

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);

With this way of getting the display metrics this is the result I get (observe how the scaled density changes with font size):

这篇关于DisplayMetrics.scaledDensity在Android中实际返回什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆