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.