Home » Android » android – TextView.setTextSize behaves abnormally – How to set text size of textview dynamically for different screens

android – TextView.setTextSize behaves abnormally – How to set text size of textview dynamically for different screens

Posted by: admin March 11, 2020 Leave a comment


Calling TextView.setTextSize() is working abnormally. Right after the call to setTextSize if we get a getTextSize its returning a much higher value that what we set it to earlier.

Here’s what we’re doing:

zoomControl.setOnZoomInClickListener(new OnClickListener() {
    public void onClick(View view) {
        float size = mViewShabad.getTextSize() + 1;

Has anyone seen this before?

How to&Answers:

The difference here is that in the setTextSize(int size) method, the unit type by default is “sp” or “scaled pixels”. This value will be a different pixel dimension for each screen density (ldpi, mdpi, hdpi).

getTextSize(), on the other hand, returns the actual pixel dimensions of the text.

You can use setTextSize(int unit, float size) to specify a unit type. The constant values for this can be found in the TypedValue class, but some of them are:

TypedValue.COMPLEX_UNIT_PX   //Pixels

TypedValue.COMPLEX_UNIT_SP   //Scaled Pixels

TypedValue.COMPLEX_UNIT_DIP  //Device Independent Pixels


this problem happend because the getTextSize() method return the size in pixels depend on screen density ! to get the Actual TextSize use this :

DisplayMetrics metrics;
metrics = getApplicationContext().getResources().getDisplayMetrics();
float Textsize =myTextView.getTextSize()/metrics.density;

i hope it solve it 🙂


if Setting change font size,something cause show error,you can do as:

setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15.f);


When we try to setText() programmitically problem with getTextSize(), returns value in px instead of sp/dp/dip and we know 1sp/dp=1.5px(screen size =240).

 titleBar.setTextSize(TypedValue.COMPLEX_UNIT_SP, (getResources().getDimension(R.dimen.text_size)*1.5f)); 

is working perfectly for me or we can use displaymatrix to px:sp/dp ratio then replace that value with 1.5f

means-> titleBar.setTextSize(TypedValue.COMPLEX_UNIT_SP, (getResources().getDimension(R.dimen.text_size)*your_sp_and_px_ratio_in_int f));


After long time struck this and finally solved like this


create dimen folder like this res/values/dimensions.xml

<?xml version="1.0" encoding="utf-8"?>

 <dimen name="textsize">8sp</dimen>



In short, if you want to zoom out your textsize

float size = mViewShabad.getTextSize()*1.1f;
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);

Because getTextSize() return UNIT_PX, then we should use UNIT_PX


Adding some extra flavor for this answer, as also ran into a bit of confusion. You should be able to drop this test into any @RunWith(AndroidJUnit4.class) test you have in your project (you’ll also need to add the dimens to your dimens.xml).

Note: All these tests pass

@Test public void testScaledFontSizes() {
    final Context context = InstrumentationRegistry.getTargetContext();

    Configuration configuration = context.getResources().getConfiguration();
    configuration.fontScale = 2.0f;
    configuration.densityDpi = 160; // mdpi, 1:1
    context.getResources().updateConfiguration(configuration, null);

    float scaledTextSize = context.getResources().getDimensionPixelSize(R.dimen.sp_15);
    assertEquals(30.0f, scaledTextSize);

    // Create a new TextView with the explicitly set configuration
    TextView textView = new TextView(context);
    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, scaledTextSize);

    // 30, because font size is scaled
    assertEquals(30.0f, textView.getTextSize());

    // This is what we *don't* want, it's scaled *twice*!
    assertEquals(60.0f, textView.getTextSize());

    // DP instead of SP tests
    float fifteenDp = context.getResources().getDimensionPixelSize(R.dimen.dp_15);
    assertEquals(15.0f, fifteenDp);

    textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, fifteenDp);
    // Still 15, because it's DP, not SP
    assertEquals(15.0f, fifteenDp);

    // 30, because setTextSize DOES font scaling
    assertEquals(30.0f, textView.getTextSize());

The big takeaway I found is that TextView.setTextSize(float) applies the font scaling, so if you pass in a dimen thats already labelled as SP instead of DP, then it will receive the font scaling twice.