Android: preferencia de tamaño de fuente para toda la aplicación

¿Es posible hacer un ajuste a nivel de aplicación para el tamaño de fuente a ser utilizado por todas las vistas que muestran texto? Me gustaría proporcionar una preferencia al usuario que debería permitir escalar todo el texto de la aplicación.

Android permite explícitamente el uso de la unidad de dimensión "sp" para texto escalable, sin embargo, no existe una forma real de establecer la "preferencia de tamaño de fuente del usuario" de una manera global.

La iteración a través de todas las vistas sobre Activación de la instancia no es realmente una opción 😉

Aquí es cómo lo hice para mi aplicación. En pocas palabras, en Activity.onCreate() obtendrás un id de recurso de estilo con un conjunto específico de tamaños de fuente y aplicarás este estilo al tema de actividad. Luego, con la actividad de preferencias, puede cambiar entre estos conjuntos.

En primer lugar en valores / attrs.xml declarar atributos para el conjunto de tamaños de fuente:

 <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> 

Luego, en valores / styles.xml declarar pocos conjuntos de tamaños de fuente:

 <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> 

A continuación, en el método onCreate() de cada actividad, añada:

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

Donde Preferences es un objeto de fachada a SharedPreferences :

 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(); } } 

Y FontStyle es:

 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; } } 

Y FontStyle.values() se utiliza como elementos para Spinner en PreferencesActivity . Así es como se ve la mía:

 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()); } } 

Y finalmente puede utilizar sus preferencias de tamaño de fuente:

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

O prefiero usar estilos, en valores / 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> 

Y puedes usarlo de esta manera:

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

Espero que mi respuesta le ayude.

Si es posible. Para hacer eso usted necesita:

  1. Declare su propia clase extendiendo TextView
  2. Úselo en todos sus diálogos / actividades solamente

Me gusta:

 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; } } 

Y ahora donde quiera que esté, puede cambiar globalmente todos los tamaños de texto a 20 en todas las vistas de texto llamando:

 SimpleTextView.setGlobalTextSize(20); 

Disparos desde la cadera aquí es la idea a considerar (no se requiere la aplicación personalizada TextView)

  1. Declare la propiedad algo como UNIVERSAL_FONT_SIZE con la idea de que se puede cambiar de la configuración pero se mantendrá entre las invocaciones de la aplicación
  2. En el método onCreate de cada una de sus Actividades, obtenga el valor de esa propiedad y guárdela como un campo
  3. Haga que su uso de código que para cada componente de texto de tamaño
  4. Nada lo impedirá de crear varias propiedades como BUTTONS_TXT_SIZE, TEXT_SIZE, LIST_TXT_SIZE, etc. y luego tendrá una lógica que toma por ejemplo el porcentaje de aumento de texto y calcula los tamaños adecuados para cada tipo de control (ya que puede tener diferentes tamaños para diferentes controles )

En la misma línea, decir que quiere hacer que esto funcione dinámicamente? Cree una clase simple (diga TextSetter) que contiene una lista interna y tiene 3 métodos: add, remove y setSize

  1. En Activity#onCreate identifique cada control que desea ajustar y utilice TextSetter#set para agregarlo a la lista
  2. Cuando el usuario quiere aumentar / disminuir el tamaño de la fuente tal vez desde el menú, cuando se maneja que acaba de ejecutar TextSetter # setSize en el que se realizará un bucle a través de la lista de controles, detectar qué tipo es y ajustar el tamaño de texto en consecuencia

Para aquellos que tienen problemas con inflar vistas con atributos personalizados de respuesta @mixels .

Si sus vistas están en el fragmento, usted necesita aplicar FontStyle también en el onCreateView() del fragmento onCreateView() o fijar los valores de estos atributos en tema de la aplicación.

Para más detailes ver mi aswer aquí .

  • Las pantallas de preferencias anidadas pierden el tema
  • ¿Cómo abrir la última pantalla de preferencias usadas?
  • Preferencias de Android, cómo establecer la dependencia de las preferencias personalizadas
  • Dependencia múltiple en checkboxpreference dependencia de android o listpreference
  • Actualizar el elemento de preferencia existente en una PreferenciaActividad al regresar de una (sub) PreferenciaScreen
  • Android cómo obtener la preferencia Pantalla de un checkBoxPreference
  • Android: inicia una preferencia personalizada desde una preferenciaActividad
  • Los valores de caché de SharedPreferences tienen sentido?
  • Android Get Keys de preferences.xml
  • Mostrar la pantalla de preferencias La primera vez que se ejecuta la aplicación y las preguntas relacionadas
  • Cargar diseño en onCreateView para las preferencias personalizadas
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.