Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: application-wide font-size preference

Tags:

Is it possible to make an application-wide setting for the font-size to be used by all views displaying text? I would like to provide a Preference to the user which should allow scaling all text in the app.

Android explicitly allows using the "sp" dimension unit for scalable text, however there is no actual way to set the "user's font size preference" in a global way.

Iterating through all views on Activity instantiation is not really an option ;-)

like image 249
ge0rg Avatar asked Feb 02 '11 16:02

ge0rg


People also ask

How do I stop system font size changing effects to Android application?

Prevent-system-font-size-changing-effects-to-androidForms Android MainActivity. cs, override the Resources and set the configuration to default to restrict the font size effect on application. Resources. UpdateConfiguration() has been deprecated in API 25.

What is Android default font size?

The body text size in Material Design is 14sp. You should think of this as the normal font size, and basically everything else a variation on it. For instance, while 14sp is the default text size when the text can be quite long, when there's only a small modal with a bit of text, it's 16sp!


2 Answers

Here it's how I made it for my app. In a few words - in Activity.onCreate() you get resource id of style with specific set of font sizes and apply this style to theme of activity. Then with preferences activity you can switch between these sets.

First of all in values/attrs.xml declare attributes for set of font sizes:

<declare-styleable name="FontStyle">     <attr name="font_small" format="dimension" />     <attr name="font_medium" format="dimension" />     <attr name="font_large" format="dimension" />     <attr name="font_xlarge" format="dimension" /> </declare-styleable> 

Then in values/styles.xml declare few sets of font sizes:

<style name="FontStyle"> </style>  <style name="FontStyle.Small">     <item name="font_small">14sp</item>     <item name="font_medium">16sp</item>     <item name="font_large">18sp</item>     <item name="font_xlarge">20sp</item> </style>  <style name="FontStyle.Medium">     <item name="font_small">18sp</item>     <item name="font_medium">20sp</item>     <item name="font_large">22sp</item>     <item name="font_xlarge">24sp</item> </style>  <style name="FontStyle.Large">     <item name="font_small">26sp</item>     <item name="font_medium">28sp</item>     <item name="font_large">30sp</item>     <item name="font_xlarge">32sp</item> </style> 

Then in onCreate() method of every activity add:

getTheme().applyStyle(new Preferences(this).getFontStyle().getResId(), true); 

where Preferences is a facade to SharedPreferences object:

public class Preferences {     private final static String FONT_STYLE = "FONT_STYLE";      private final Context context;      public Preferences(Context context) {         this.context = context;     }      protected SharedPreferences open() {         return context.getSharedPreferences("prefs", Context.MODE_PRIVATE);     }      protected Editor edit() {         return open().edit();     }      public FontStyle getFontStyle() {         return FontStyle.valueOf(open().getString(FONT_STYLE,             FontStyle.Medium.name()));     }      public void setFontStyle(FontStyle style) {         edit().putString(FONT_STYLE, style.name()).commit();     } } 

and FontStyle is:

public enum FontStyle {     Small(R.style.FontStyle_Small, "Small"),      Medium(R.style.FontStyle_Medium, "Medium"),      Large(R.style.FontStyle_Large, "Large");      private int resId;     private String title;      public int getResId() {         return resId;     }      public String getTitle() {         return title;     }      FontStyle(int resId, String title) {         this.resId = resId;         this.title = title;     } } 

And FontStyle.values() is used as items for Spinner in your PreferencesActivity. That's how mine looks like:

public class PreferencesActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) {     getTheme().applyStyle(new Preferences(this).getFontStyle().getResId(), true);     super.onCreate(savedInstanceState);      setContentView(R.layout.preferences);      Preferences prefs = new Preferences(this);      Spinner fontStylesView = (Spinner) findViewById(R.id.font_styles);     FontStylesAdapter adapter = new FontStylesAdapter(this,             R.layout.font_styles_row, FontStyle.values());     fontStylesView.setAdapter(adapter);      fontStylesView.setSelection(prefs.getFontStyle().ordinal()); }  @Override public boolean onCreateOptionsMenu(Menu menu) {     MenuInflater inflater = getSupportMenuInflater();     inflater.inflate(R.menu.preferences, menu);     return super.onCreateOptionsMenu(menu); }  @Override public boolean onOptionsItemSelected(MenuItem item) {     switch (item.getItemId()) {     case R.id.menu_done:         onMenuDone();         finish();         return true;     case R.id.menu_cancel:         finish();         return true;     default:         return false;     } }  private void onMenuDone() {     Preferences prefs = new Preferences(this);      Spinner fontStylesView = (Spinner) findViewById(R.id.font_styles);     prefs.setFontStyle((FontStyle) fontStylesView.getSelectedItem()); } } 

And finally you can use your font size preferences:

<TextView android:textSize="?attr/font_large" /> 

Or I prefer using styles, in values/styles.xml add:

<style name="Label" parent="@android:style/Widget.TextView">     <item name="android:textSize">?attr/font_medium</item>     <item name="android:layout_width">wrap_content</item>     <item name="android:layout_height">wrap_content</item> </style>  <style name="Label.XLarge">     <item name="android:textSize">?attr/font_xlarge</item> </style> 

And you can use it in this way:

<TextView style="@style/Label.XLarge" /> 

I hope my answer will help you.

like image 183
mixel Avatar answered Oct 16 '22 15:10

mixel


Yes, it's possible. To do that you need to:

  1. Declare your own class extending TextView
  2. Use in all your dialogs/activities only it

Like:

public class SimpleTextView extends TextView {     private static final float DEFAULT_TEXT_SIZE=12.0;     private static float textSize=DEFAULT_TEXT_SIZE;      public SimpleTextView(Context context)     {         super(context);         this.setTextSize(textSize);     }      public SimpleTextView(Context context, AttributeSet attrs)     {         super(context, attrs);         this.setTextSize(textSize);     }      public SimpleTextView(Context context, AttributeSet attrs, int defStyle)     {         super(context, attrs, defStyle);         this.setTextSize(textSize);     }      public static void setGlobalSize(float size)     {         textSize=size;     }      public static float getGlobalSize()     {         return textSize;     } } 

And now whereever you're you can globally change all text sizes to 20 in all textviews just calling:

SimpleTextView.setGlobalTextSize(20); 
like image 40
Barmaley Avatar answered Oct 16 '22 13:10

Barmaley