Establecer estilos globales para Vistas en Android

125

Digamos que quiero tener todas las TextViewinstancias en mi aplicación textColor="#ffffff". ¿Hay alguna manera de configurar eso en un lugar en lugar de configurarlo para cada uno TextView?

Emanuil Rusev
fuente
1
He actualizado mi pregunta para que se complete.
Cristian
¡Estoy haciendo algo similar AQUÍ! stackoverflow.com/questions/17103894/…
toobsco42

Respuestas:

250

En realidad, puede establecer un estilo predeterminado para TextViews (y la mayoría de los otros widgets integrados) sin necesidad de hacer una clase personalizada de Java o configurar el estilo individualmente.

Si echa un vistazo a themes.xmlla fuente de Android, verá un montón de atributos para el estilo predeterminado para varios widgets. La clave es el atributo textViewStyle(o editTextStyle, etc.) que anula en su tema personalizado. Puede anularlos de la siguiente manera:

Crea un styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="android:Theme">
    <item name="android:textViewStyle">@style/MyTextViewStyle</item>
</style>

<style name="MyTextViewStyle" parent="android:Widget.TextView">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
</style>
</resources>

Luego solo aplica ese tema a tu aplicación en AndroidManifest.xml:

<application […] android:theme="@style/MyTheme">

¡Y todas sus vistas de texto tendrán el estilo predeterminado en MyTextViewStyle(en este caso, negrita y rojo)!

Esto se probó en dispositivos desde el nivel API 4 en adelante y parece funcionar muy bien.

Steve Pomeroy
fuente
1
La solución más elegante que vi hasta ahora.
Italo Borssatto
@ Steve, si incluyo el elemento <item name="android:textViewStyle">@style/MyTextViewStyle</item>en el estilo MyTheme y luego aplico el estilo a mi aplicación, todos mis correos electrónicos TextViewse mostrarán de acuerdo con el estilo (incluso el nombre de la aplicación en la barra de acción). ¿Cómo solucionar el problema con la barra de acción? Quiero que tenga la apariencia predeterminada. Github
Maksim Dmitriev
@Steve, Cómo aplicar el tema (barra de acción y widget) en la aplicación
Pratik Butani
No estoy seguro de cómo diferenciar la ActionBar de otras cosas. Es posible que pueda encontrar donde esté configurado su estilo de ActionBar y luego colocarlo <item name="android:textViewStyle">@style/MyTextViewStyle</item>allí, simplemente señalando el valor predeterminado de ActionBar (o algo similar)
Steve Pomeroy
@StevePomeroy esto no funciona para mí ... ¿puede proporcionar algún soporte? Mi estilo para TextViews permanece igual. ¿Hay un mínimo de elementos que necesito configurar o hay algunos elementos que no puedo configurar?
Mike
52

Hay dos formas de hacerlo:

1. Usando estilos

Puede definir sus propios estilos creando archivos XML en el res/valuesdirectorio. Entonces, supongamos que desea tener texto rojo y en negrita, luego crea un archivo con este contenido:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="MyRedTheme" parent="android:Theme.Light">
    <item name="android:textAppearance">@style/MyRedTextAppearance</item>
  </style>
  <style name="MyRedTextAppearance" parent="@android:style/TextAppearance">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
  </style>
</resources>

Puedes nombrarlo como quieras, por ejemplo res/values/red.xml. Entonces, lo único que tiene que hacer es usar esa vista en los widgets que desee, por ejemplo:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    style="@style/MyRedTheme"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

Para mayor referencia, puede leer este artículo: Comprender los temas y estilos de Android

2. Usando clases personalizadas

Esta es otra forma posible de lograr esto, y sería proporcionar el suyo propio TextViewque establezca el color del texto siempre como lo desee; por ejemplo:

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.TextView;
public class RedTextView extends TextView{
    public RedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTextColor(Color.RED);
    }
}

Luego, solo debe tratarlo como normal TextViewen su archivo XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<org.example.RedTextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

Si usa una u otra opción depende de sus necesidades. Si lo único que quiere hacer es modificar la apariencia, entonces el mejor enfoque es el primero. Por otro lado, si desea cambiar la apariencia y agregar alguna funcionalidad nueva a sus widgets, el segundo es el camino a seguir.

Cristian
fuente
Se debe preferir el uso de clases personalizadas, ya que es un enfoque más limpio y ayuda a mantener el peso del archivo xml.
Amit Kumar
@AmitKumar ¡No, no deberían! En este caso particular, esto significaría usar una clase personalizada separada para cada valor de atributo diferente. Esto produce una gran cantidad de código de relleno y hace que el diseño real ya no sea legible (tendrá que visitar cada clase para ver qué está haciendo en lugar de solo leer algunas líneas xml). Las clases personalizadas solo deben usarse si modifica el comportamiento, pero no si el único cambio es el aspecto de la vista.
Andre
¿No es posible establecer el estilo de una vista personalizada desde xml? ¿Por qué no podemos usarlo en el custom_view_layout.xmlarchivo que se usa para inflar una clase personalizada?
lucidbrot
5

Para el color de texto predeterminado TextView, configure android:textColorTertiarysu tema en el color deseado:

<item name="android:textColorTertiary">@color/your_text_color</item>

Muchos otros colores de control de Android se pueden controlar usando atributos de marco o atributos de biblioteca de soporte si usa la biblioteca de soporte.

Para obtener una lista de atributos que se pueden establecer, revisar el código fuente de Android de styles.xmly themes.xml, o esta muy útiles GIST por Dan Lew, pruebe a cambiar cada valor y ver lo que cambian en la pantalla.

hidro
fuente
¡Gracias hombre! Pasé mucho tiempo descubriendo por qué textColorPrimary no funciona.
pratt
3

Defina un estilo y úselo en cada widget, defina un tema que anule el valor predeterminado de Android para ese widget o defina un recurso de cadena y haga referencia a él en cada widget

TWH
fuente