24

I have created Spinner with the list of Font Sizes from "8" to "46" . I could be able to click the font Size and in a spinner it has shown me .

My need is, if i click the Font Size "26" inside a Spinner then it should be applied to my whole project. Like applying to my Screen, Textview appearance, Edittext - Bold/ Italic, etc. Again if i click 46 size then it should be apply to my whole project.

How could i do this by programmatically ?

Achiever
  • 1,626
  • 10
  • 30
  • 54
  • 1
    I assume you want to create some kind of a preference to change the text size throughout your app. You can create styles for that. http://developer.android.com/guide/topics/ui/themes.html – Siddharth Lele Oct 03 '12 at 08:08
  • But Dynamically without using Styles and Themes. How could i do that? Any ideas !!! – Achiever Oct 03 '12 at 08:26
  • Does this answer your question? [Android: How do I set the textsize for a layout?](https://stackoverflow.com/questions/8380020/android-how-do-i-set-the-textsize-for-a-layout) And the answer there is exactly what you need. – Marian Paździoch Apr 20 '20 at 11:54

6 Answers6

33

Android documentation is not specific on the most efficient way to change the font size globally through the user’s selection at application level.

There is a problem I think with the answer given by Black Devil.

The problem is that many of the Android widgets subclass TextView, such as Button, RadioButton, and CheckBox. Some of these are indirect subclasses of TextView, which makes implementing customized version of TextView in these classes very difficult.

However as pointed out by Siddharth Lele in his comment, using styles or themes is much better way to handle change in the text size throughout the app.

We set styles for layouts to control the look and feel of the view. Themes are essentially just collections of these styles. However, we can use a theme just for text size settings; without defining values for every property. Using a theme over styles provides us with one huge advantage: we can set a theme for the entire view programmatically.

theme.xml

<resources>
    <style name="FontSizeSmall">
        <item name="android:textSize">12sp</item>
    </style>
    <style name="FontSizeMedium">
        <item name="android:textSize">16sp</item>
    </style>
    <style name="FontSizeLarge">
        <item name="android:textSize">20sp</item>
    </style>
</resources>

Create a class to handle loading our preferences:

public class BaseActivity extends Activity {
    @Override
    public void onStart() {
        super.onStart();

        // Enclose everything in a try block so we can just
        // use the default view if anything goes wrong.
        try {
            // Get the font size value from SharedPreferences.
            SharedPreferences settings =
                getSharedPreferences("com.example.YourAppPackage", Context.MODE_PRIVATE);

            // Get the font size option.  We use "FONT_SIZE" as the key.
            // Make sure to use this key when you set the value in SharedPreferences.
            // We specify "Medium" as the default value, if it does not exist.
            String fontSizePref = settings.getString("FONT_SIZE", "Medium");

            // Select the proper theme ID.
            // These will correspond to your theme names as defined in themes.xml.
            int themeID = R.style.FontSizeMedium;
            if (fontSizePref == "Small") {
                themeID = R.style.FontSizeSmall;
            }
            else if (fontSizePref == "Large") {
                themeID = R.style.FontSizeLarge;
            }

            // Set the theme for the activity.
            setTheme(themeID);
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }

Finally, create activities by extending BaseActivity, like this:

public class AppActivity extends BaseActivity{
}

As most of the application have a much fewer amount of Activities than TextViews or widgets that inherit TextView. This will be exponentially so as complexity increases, so this solution requires less changes in code.

Thanks to Ray Kuhnell

Community
  • 1
  • 1
Ritesh Gune
  • 16,629
  • 6
  • 44
  • 72
26

you can scale to text size of your app up/down using base activity Configuration, make all activities inherent base activity.

Scale normal value is 1.0, 2.0 would double the font size and .50 would make it half.

public  void adjustFontScale( Configuration configuration,float scale) {

    configuration.fontScale = scale;
    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
  • 984
  • 11
  • 18
  • 1
    Works pretty well. Does not scale toolbar title size, because that's defined in 'dp' deep down in the themes. – Ridcully Sep 26 '18 at 12:03
  • 2
    The code as it is provided, does not take the user's scale settings into account (in Settings/Accessibility/Font size) but that can be added quite easily. – Ridcully Sep 26 '18 at 12:28
  • 2
    Thanks this worked. In order to take acount user's scale I used this: systemScale = Settings.System.getFloat(context.getContentResolver(), Settings.System.FONT_SCALE, 1f); configuration.fontScale = scale * systemScale; //rest of code – Jerry Sha Mar 06 '19 at 21:14
  • 1
    easiest way to achieve that goal is this way... i implemented this and i'm a satisfy developer now! – Salar Arabpour Sep 22 '20 at 14:15
5

The probable solution would be you create a base class which extends TextView, and use this text view class as edit text. Hope you are asking for size in first screen. In any case, u set the text size in the base class. This will solve your problem.

like u create this class in package com.example and class name is BaseTextView, then in xml file instead of <TextView .../> you will write <com.example.BaseTextView ... />

Hope this helps.

Android
  • 3,828
  • 9
  • 46
  • 79
  • @ Meena Rengarajan can you explain little more as you have accepted it as a right answer. i did same but not working. some hints plz – Krishna Shrestha Nov 18 '12 at 11:47
0

Create a function and pass the spinner size value as

void setSize(int size){
...
setTextSize()
// on All of the layout texts and views on screen

}

Call setTextSize() on all of your views and layout texts on the screen.

Check out the Documentations Here

Rajeev N B
  • 1,365
  • 2
  • 12
  • 24
0

To scale the font size of all components(mean whole application), there is pretty well approach which is implemented and tested trough several devices. This solution could be applied for cases like; declaring dp size unit statically(android sp by default) , scaling to desired font sizes and etc.

The solution is similar to answer given by Usama Saeed US but will cover all buggy cases.

Declare static util method which will scale font size.

    //LocaleConfigurationUtil.class
    public static Context adjustFontSize(Context context){
        Configuration configuration = context.getResources().getConfiguration();
        // This will apply to all text like -> Your given text size * fontScale
        configuration.fontScale = 1.0f;

        return context.createConfigurationContext(configuration);
    }

In your all activities, override the attachBaseContext and call util method in onCreate.

   @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(LocaleConfigurationUtil.adjustFontSize(newBase));
    }

   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LocaleConfigurationUtil.adjustFontSize(this);
    }

If you are using fragments then override onAttach method

@Override
public void onAttach(Context context) {
super.onAttach(LocaleConfigurationUtil.adjustFontSize(context));
}
-1

I'm not sure if it help. But there is something called "SSP" - Scalable size Unit for Text. Add this to your build gradle

implementation 'com.intuit.ssp:ssp-android:1.0.6'

And this to use

android:textSize="@dimen/_22ssp"

https://github.com/intuit/ssp