186

I want to specify my own text size in my application, but I am having a problem doing this.

When I change the font size in the device settings, the font size of my application TextView also changes.

030
  • 8,013
  • 8
  • 63
  • 100
Vikasdeep Singh
  • 17,777
  • 9
  • 70
  • 93
  • 2
    it is default behavior that if you change the font size of your device native font then it also effect to your application font size. – Shreyash Mahajan Nov 07 '12 at 07:16
  • you can find answer from here http://stackoverflow.com/questions/16706076/font-size-and-images-for-different-devices/16910589#16910589 – Bhavesh Jethani Jul 16 '14 at 06:47
  • Use sp for text size…because but it is scaled by the user’s font size preference. Use dp for everything else. – live-love Nov 22 '17 at 18:46

15 Answers15

250

Actually, Settings font size affects only sizes in sp. So all You need to do - define textSize in dp instead of sp, then settings won't change text size in Your app.

Here's a link to the documentation: Dimensions

However please note that the expected behavior is that the fonts in all apps respect the user's preferences. There are many reasons a user might want to adjust the font sizes and some of them might even be medical - visually impaired users. Using dp instead of sp for text might lead to unwillingly discriminating against some of your app's users.

i.e:

android:textSize="32dp"
Snehal Parmar
  • 4,437
  • 3
  • 32
  • 42
sandrstar
  • 11,931
  • 7
  • 58
  • 64
  • 13
    A long while back I wanted to know if there were any rule for when I should use `sp` and when I should use `dp`. I got a really good response here: http://stackoverflow.com/questions/11638691/android-sp-vs-dp-texts-what-would-adjust-the-scale-and-what-is-the-philosoph – Sam Sep 25 '15 at 09:20
130

The easiest to do so is simply to use something like the following:

android:textSize="32sp"

If you'd like to know more about the textSize property, you can check the Android developer documentation.

Qantas 94 Heavy
  • 14,790
  • 31
  • 61
  • 78
Evan Long
  • 1,357
  • 1
  • 8
  • 2
  • 1
    this is actually why the TS has the issue, using 'sp' instead of 'dp' – Boy Aug 23 '15 at 11:16
  • 9
    I still don't know why there are 100 upvotes. because if we use sp for set textsize in application. Then we change the font size in Setting, the TextView in application also change – Linh Feb 28 '17 at 04:04
  • how does this answer the question? – Siddarth G Apr 14 '20 at 14:17
51

Use the dimension type of resources like you use string resources (DOCS).

In your dimens.xml file, declare your dimension variables:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <dimen name="textview_height">25dp</dimen>
  <dimen name="textview_width">150dp</dimen>
  <dimen name="ball_radius">30dp</dimen>
  <dimen name="font_size">16sp</dimen>
</resources>

Then you can use these values like this:

<TextView
   android:layout_height="@dimen/textview_height"
   android:layout_width="@dimen/textview_width"
   android:textSize="@dimen/font_size"/>

You can declare different dimens.xml files for different types of screens. Doing this will guarantee the desired look of your app on different devices.

When you don't specify android:textSize the system uses the default values.

Community
  • 1
  • 1
ashakirov
  • 10,395
  • 4
  • 37
  • 39
25

Also note that if the textSize is set in code, calling textView.setTextSize(X) interprets the number (X) as SP. Use setTextSize(TypedValue.COMPLEX_UNIT_DIP, X) to set values in dp.

030
  • 8,013
  • 8
  • 63
  • 100
Arpit
  • 2,167
  • 1
  • 17
  • 29
14

It is not a good thing to have to specify DIP or SP again by code when already defined in a dimen.xml file.

I think that the best option is to use PX when using a dimen.xml value :

tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.txt_size));

This way, you can switch from DP to SP if needed in dimen.xml file without having to change any code.

mba
  • 411
  • 6
  • 10
9

simple way to prevent the whole app from getting effected by system font size is to updateConfiguration using a base activity.

//in base activity add this code.
public  void adjustFontScale( Configuration configuration) {

    configuration.fontScale = (float) 1.0;
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(metrics);
    metrics.scaledDensity = configuration.fontScale * metrics.density;
    getBaseContext().getResources().updateConfiguration(configuration, metrics);

}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    adjustFontScale( getResources().getConfiguration());
}
Usama Saeed US
  • 709
  • 9
  • 12
2

this solutions is with Kotlin and without using the deprecated function resources.updateConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        adjustFontScale(resources.configuration)
    }

    private fun adjustFontScale(configuration: Configuration?) {
        configuration?.let {
            it.fontScale = 1.0F
            val metrics: DisplayMetrics = resources.displayMetrics
            val wm: WindowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
            wm.defaultDisplay.getMetrics(metrics)
            metrics.scaledDensity = configuration.fontScale * metrics.density

            baseContext.applicationContext.createConfigurationContext(it)
            baseContext.resources.displayMetrics.setTo(metrics)

        }
    }

Observation: this is the same solution as the above but udpated with Kotlin

Jorge Casariego
  • 20,634
  • 6
  • 84
  • 96
1

this may help. add the code in your custom Application or BaseActivity

/**
 * 重写 getResource 方法,防止系统字体影响
 *
 * @return
 */
@Override
public Resources getResources() {
    Resources resources = super.getResources();
    if (resources != null && resources.getConfiguration().fontScale != 1) {
        Configuration configuration = resources.getConfiguration();
        configuration.fontScale = 1;
        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
    }
    return resources;
}

however, Resource#updateConfiguration is deplicated in API level 25, which means it will be unsupported some day in the future.

Arno_J
  • 11
  • 2
1

You can use this code:

android:textSize="32dp"

it solves your problem but you must know that you should respect user decisions. by this, changing text size from device settings will not change this value. so that's why you need to use sp instead of dp. So my suggestion is to review your app with different system font sizes(small,normal,big,...)

Hossein Karami
  • 540
  • 7
  • 10
1

for kotlin, it works for me

priceTextView.textSize = 12f
Shihab Uddin
  • 4,947
  • 2
  • 43
  • 69
1

change the DP to sp it is good pratice for android android:textSize="18sp"

sanjay
  • 379
  • 4
  • 18
1

in android 8 this solution work for me

add this code in base activity

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(newBase);
    final Configuration override = new Configuration(newBase.getResources().getConfiguration());
    override.fontScale = 1.0f;
    applyOverrideConfiguration(override);
}

source https://stackoverflow.com/a/57225687/7985871

emad pirayesh
  • 474
  • 5
  • 9
0

If units used are SP, not DP, and you want to override system font scaling, all you do is override one method in activity - see this post.

resources.updateConfiguration is deprecated and buggy (on Oreo I had issues with formatted text).

Maxim Saplin
  • 1,353
  • 19
  • 13
0

Override getResources() in Activity.

Set TextView's size in sp as usual like android:textSize="32sp"

override fun getResources(): Resources {
    return super.getResources().apply {
        configuration.fontScale = 1F
        updateConfiguration(configuration, displayMetrics)
    }
}
barbsan
  • 3,238
  • 11
  • 18
  • 27
jay
  • 11
  • 1
0

I usually change size from dimen in resources file

<resources>
    <dimen name="siez_1">40px</dimen>
    <dimen name="siez_2">50px</dimen>
    <dimen name="siez_3">60px</dimen>

</resources>