237

If I assign an integer value to change a certain text size of a TextView using java code, the value is interpreted as pixel (px).

Now does anyone know how to assign it in sp?

user2342558
  • 5,567
  • 5
  • 33
  • 54
capecrawler
  • 67,353
  • 7
  • 31
  • 34

12 Answers12

597

http://developer.android.com/reference/android/widget/TextView.html#setTextSize%28int,%20float%29

Example:

textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 65);
John Leehey
  • 22,052
  • 8
  • 61
  • 88
Santosh
  • 13,251
  • 5
  • 24
  • 12
  • 21
    Since SP stands for scaled *pixels* you'll need to reduce the size by screen density. It's easily done as follows: SCREEN_DENSITY = getResources().getDisplayMetrics().density; yourView.setTextSize(TypedValue.COMPLEX_UNIT_SP, (desiredTextHeightInSP / SCREEN_DENSITY); – PeteH Sep 13 '14 at 23:50
  • 4
    The solution didn't work for me when I tried to collect SP from resources. PeteH, you got me on the right track! The following did the trick for me: ... float textSize = getResources().getDimension(R.dimen.textsize) / getResources().getDisplayMetrics().density; myTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize); – P Kuijpers Oct 22 '14 at 13:53
  • 58
    If you get the sp size from your resources, you should use COMPLEX_UNIT_PX, like this: `textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.my_text_size_in_sp));` Getting your text size this way will already convert SP to PX, taking both screen density and text scale factor in account. – Divisible by Zero Aug 12 '15 at 09:30
  • The provided solution worked for me as shown. Thanks! – Martin Erlic Jan 23 '17 at 16:33
  • The actual answer did it for me, i dont why but suggestions from comments made my text go microscopic while trying to set sp tp 11 – MDT Jun 21 '21 at 12:47
42

Cleaner and more reusable approach is

define text size in dimens.xml file inside res/values/ directory:

<resources>
   <dimen name="text_medium">14sp</dimen>
</resources>

and then apply it to the TextView:

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.text_medium));
Donald Duck
  • 8,409
  • 22
  • 75
  • 99
klimat
  • 24,711
  • 7
  • 63
  • 70
  • I would argue that XML is not "in Java code" as the OP requested. This doesn't allow the code a way to set the font to something not already predetermined by the programmer. – David Rector Apr 06 '23 at 01:32
37

You can use a DisplayMetrics object to help convert between pixels and scaled pixels with the scaledDensity attribute.

DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
pixelSize = (int)scaledPixelSize * dm.scaledDensity; 
David Webb
  • 190,537
  • 57
  • 313
  • 299
  • 1
    This will take the screen density scaling factor into account but not the text scale factor that the user may have specified via settings. I believe @Santosh's solution will take this factor into account whereas this snippet does not. – greg7gkb May 29 '14 at 18:08
  • 4
    But sometimes you are not able to use the method of @Santosh for example when you write a Paint into a canvas. Then this method comes handy and works pretty well, therefore thumbs up for these two answers! – byemute Sep 25 '14 at 09:21
  • 1
    @greg7gkb not true, documentation says ```may be adjusted in smaller increments at runtime based on a user preference for the font size``` so the font size **will** be taken into account. – Luca Vitucci Dec 14 '15 at 10:35
21

Based on the the source code of setTextSize:

public void setTextSize(int unit, float size) {
    Context c = getContext();
    Resources r;

    if (c == null)
        r = Resources.getSystem();
    else
        r = c.getResources();

    setRawTextSize(TypedValue.applyDimension(
        unit, size, r.getDisplayMetrics()));
}

I build this function for calulating any demension to pixels:

int getPixels(int unit, float size) {
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    return (int)TypedValue.applyDimension(unit, size, metrics);
}

Where unit is something like TypedValue.COMPLEX_UNIT_SP.

rekire
  • 47,260
  • 30
  • 167
  • 264
17

When the accepted answer doesn't work (for example when dealing with Paint) you can use:

float spTextSize = 12;
float textSize = spTextSize * getResources().getDisplayMetrics().scaledDensity;
textPaint.setTextSize(textSize);
pomber
  • 23,132
  • 10
  • 81
  • 94
13

By default setTextSize, without units work in SP (scales pixel)

public void setTextSize (float size)

Added in API level 1 Set the default text size to the given value, interpreted as "scaled pixel" units. This size is adjusted based on the current density and user font size preference.

DiLDoST
  • 335
  • 3
  • 12
Zeus Monolitics
  • 832
  • 9
  • 19
11

Thanks @John Leehey and @PeterH:

desiredSp = getResources().getDimension(R.dimen.desired_sp);
density = getResources().getDisplayMetrics().density;
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, desiredSp / density);

The thing is if you define R.dimen.desired_sp to 25 in your dimen.xml

  1. On non-HD Device: desiredSp is still 25, density = 1
  2. On HD Device(like Nexus 7 2nd Generation): desiredSp becomes 50 ish, density = 2
macio.Jun
  • 9,647
  • 1
  • 45
  • 41
10
semeTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 
                       context.getResources().getDimension(R.dimen.text_size_in_dp))
William Hu
  • 15,423
  • 11
  • 100
  • 121
4

This is code for the convert PX to SP format. 100% Works

view.setTextSize(TypedValue.COMPLEX_UNIT_PX, 24);
Kamran Gasimov
  • 1,445
  • 1
  • 14
  • 11
  • Doesn't this set the size based on the number of pixels while the OP asked how to set it in SP? How does this answer their question? – David Rector Apr 06 '23 at 01:33
3

From Api level 1, you can use the public void setTextSize (float size) method.

From the documentation:

Set the default text size to the given value, interpreted as "scaled pixel" units. This size is adjusted based on the current density and user font size preference.

Parameters: size -> float: The scaled pixel size.

So you can simple do:

textView.setTextSize(12); // your size in sp
user2342558
  • 5,567
  • 5
  • 33
  • 54
2

In Kotlin 'androidx.core:core-ktx:1.10.0', this way is useful

import android.util.TypedValue


.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12F)

here 12F = 12sp

Mori
  • 2,653
  • 18
  • 24
1

After trying all the solutions and none giving acceptable results (maybe because I was working on a device with default very large fonts), the following worked for me (COMPLEX_UNIT_DIP = Device Independent Pixels):

textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
tsig
  • 148
  • 2
  • 6