How to set text size using dimension from xml at runtime programmatically?

AndroidTextviewDimensions

Android Problem Overview


In dimens.xml, I have:

<dimen name="text_medium">18sp</dimen>

In runtime, I get this value and set the text size of a text view:

int size = context.getResources().getDimensionPixelSize(R.dimen.text_medium);
textView.setTextSize(size).

On a 10″ tablet (1280 x 800), everything is ok; but on a phone (800 x 480), the text view has a very large font. On the tablet, the size equals 18; on the phone, it's 27.

If I set the size manually by:

textView.setTextSize(size)

the size is normal on both devices.

Android Solutions


Solution 1 - Android

Add dimension in dimens.xml:

   <dimen name="text_medium">18sp</dimen>

Set the size in code:

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.text_medium));

Solution 2 - Android

Both methods getDimensionPixelSize() and getDimension() use screen density to calculate pixels. Your phone screen density is obviously hdpi (240dpi) so it uses 1.5 scale to convert dp to sp. Simple math 18 * 1.5 = 27.

It seems that your tablet density is mdpi (160dpi) so scale is just 1:1.

But if you compare real size of both texts it should be the same.

The best way is just create two dimens.xml files one in values folder for phone, and another in values-sw600dp for tablets (you could use also values-sw720dp-land folder to store dimensions for 10 inch tablets in landscape orientation).

You could read more about dimensions in Android at: http://android4beginners.com/2013/07/appendix-c-everything-about-sizes-and-dimensions-in-android/

Solution 3 - Android

You can use sdp (Scalable desnsity pixels) https://github.com/intuit/sdp in place of dp, this will definately save your life

Solution 4 - Android

To expand on Kostek Poland's answer,

The reason why your text size doesn't appear as expected is because in this line:

int size = context.getResources().getDimensionPixelSize(R.dimen.text_medium);

getDimensionPixelSize() converts "18sp" to pixel size, so the returned value is a different value than 18. Lets say for example the method returns a value of 23. Therefore when this line is executed:

textView.setTextSize(size)

The method sets your text size to 23sp, so your text size will appear larger than expected.

The Solution is to use this line instead when setting your text size:

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.text_medium));

This works because the first argument states that the second argument is of type pixel. So now if the second argument is 23 then it wont be treated like it is 23sp, but instead means 23 pixels which is equivalent to the 18sp but in pixel units.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYura ShinkarevView Question on Stackoverflow
Solution 1 - AndroidKostek PolandView Answer on Stackoverflow
Solution 2 - AndroidAndroid4BeginnersView Answer on Stackoverflow
Solution 3 - AndroidAayushman chaudhoryView Answer on Stackoverflow
Solution 4 - Androidmbisonsf5View Answer on Stackoverflow