Estilos y temas

Los estilos y temas en Android te permiten separar los detalles de diseño de tu app de la estructura y el comportamiento de la IU, de forma similar a las hojas de estilo en el diseño web.

Un estilo es una colección de atributos que especifican la apariencia de un solo View. Un estilo puede especificar atributos como el color y el tamaño de fuente, el color de fondo y mucho más.

Un tema es un tipo de estilo que se aplica a toda una app, actividad o jerarquía de vistas, no solo a una vista individual. Cuando aplicas tu estilo como tema, cada vista de la app o actividad aplica cada atributo de estilo que admite. Los temas también pueden aplicar estilos a elementos que no se ven, como la barra de estado y el fondo de la ventana.

Los estilos y los temas se declaran en un archivo de recursos de estilo en res/values/, generalmente llamado styles.xml.

Figura 1: Se aplicaron dos temas a la misma actividad: Theme.AppCompat (izquierda) y Theme.AppCompat.Light (derecha)

Crea y aplica un estilo

Para crear un nuevo estilo o tema, abre el archivo res/values/styles.xml de tu proyecto. Para cada estilo que desees crear, sigue estos pasos:

  1. Agrega un elemento <style> con un nombre que identifique el estilo de forma exclusiva.
  2. Agrega un elemento <item> para cada atributo de estilo que quieras definir.

    El name en cada elemento especifica un atributo que de otro modo usarías como un atributo XML en tu diseño. El valor del elemento <item> es el valor de ese atributo.

Por ejemplo, si defines el siguiente estilo:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <style name="GreenText" parent="TextAppearance.AppCompat">
            <item name="android:textColor">#00FF00</item>
        </style>
    </resources>
    

Puedes aplicar el estilo a una vista de la siguiente manera:

    <TextView
        style="@style/GreenText"
        ... />
    

Cada atributo especificado en el estilo se aplica a esa vista si esta lo acepta. La vista simplemente ignora los atributos que no acepta.

Nota: Solo el elemento al que le agregas el atributo style recibe esos atributos de estilo; cualquier vista secundaria no aplica los estilos. Si deseas que las vistas secundarias hereden estilos, aplica el estilo con el atributo android:theme.

Sin embargo, en vez de aplicar un estilo a las vistas individuales, por lo general, aplicarás estilos como un tema para toda tu app, actividad o colección de vistas.

Extiende y personaliza un estilo

Cuando creas tus propios estilos, siempre debes extender un estilo existente del marco de trabajo o la biblioteca de compatibilidad para mantener la compatibilidad con los estilos de IU de la plataforma. Para extender un estilo, especifica el que quieres extender con el atributo parent. Luego, puedes anular los atributos de estilo heredados y agregar otros nuevos.

Por ejemplo, puedes heredar la apariencia de texto predeterminada de la plataforma de Android y modificarla de la siguiente manera:

    <style name="GreenText" parent="@android:style/TextAppearance">
        <item name="android:textColor">#00FF00</item>
    </style>
    

Sin embargo, siempre debes heredar tus estilos de apps principales de la biblioteca de compatibilidad de Android. Los estilos de la biblioteca de compatibilidad ofrecen compatibilidad con Android 4.0 (API nivel 14) y versiones posteriores, ya que optimizan cada estilo para los atributos de IU disponibles en cada versión. Los estilos de la biblioteca de compatibilidad suelen tener un nombre similar al estilo de la plataforma, pero con AppCompat incluido.

Para heredar estilos de una biblioteca o tu propio proyecto, declara el nombre del estilo principal sin la parte @android:style/ que se muestra arriba. En el siguiente ejemplo, se heredan estilos de apariencia de texto de la biblioteca de compatibilidad:

    <style name="GreenText" parent="TextAppearance.AppCompat">
        <item name="android:textColor">#00FF00</item>
    </style>
    

También puedes heredar estilos (excepto los de la plataforma) extendiendo el nombre de un estilo con una notación de puntos en vez de usar el atributo parent. Es decir, puedes prefijar el nombre de tu estilo con el nombre del estilo que deseas heredar, separados por un punto. Por lo general, debes hacer esto solo cuando extiendes tus propios estilos, no los estilos de otras bibliotecas. Por ejemplo, el siguiente estilo hereda todos los estilos del estilo GreenText anterior y, luego, aumenta el tamaño del texto:

    <style name="GreenText.Large">
        <item name="android:textSize">22dp</item>
    </style>
    

Puedes seguir heredando estilos como este tantas veces como quieras encadenando más nombres.

Nota: Si usas la notación de puntos para extender un estilo, y también incluyes el atributo parent, los estilos primarios anulan cualquier estilo heredado a través de ella.

Para descubrir qué atributos puedes declarar con una etiqueta <item>, consulta la tabla "Atributos XML" en las distintas referencias de clase. Todas las vistas admiten los atributos XML de la clase View base, y muchas vistas agregan sus propios atributos especiales. Por ejemplo, los atributos XML de TextView incluyen el atributo android:inputType que puedes aplicar a una vista de texto que recibe entradas, como un widget EditText.

Aplica un estilo como un tema

Puedes crear un tema de la misma manera en que creas estilos. La diferencia es cómo lo aplicas: en vez de aplicar un estilo con el atributo style en una vista, aplica un tema con el atributo android:theme en la etiqueta <application> o en una etiqueta <activity> en el archivo AndroidManifest.xml.

Por ejemplo, aquí se muestra cómo aplicar el tema "oscuro" de material design de la biblioteca de compatibilidad de Android a toda la app:

    <manifest ... >
        <application android:theme="@style/Theme.AppCompat" ... >
        </application>
    </manifest>
    

Aquí se muestra cómo aplicar el tema "claro" a una sola actividad:

    <manifest ... >
        <application ... >
            <activity android:theme="@style/Theme.AppCompat.Light" ... >
            </activity>
        </application>
    </manifest>
    

Ahora, cada vista de la app o actividad aplica los estilos definidos en el tema dado. Si una vista solo admite algunos de los atributos declarados en el estilo, solo aplica esos atributos e ignora los que no admite.

A partir de Android 5.0 (API nivel 21) y la biblioteca de compatibilidad de Android v22.1, también puedes especificar el atributo android:theme para una vista del archivo de diseño. Esto modifica el tema para esa vista y cualquier vista secundaria, lo que es útil para alterar las paletas de colores del tema en una parte específica de tu interfaz.

Los ejemplos anteriores muestran cómo aplicar un tema como Theme.AppCompat que proporciona la biblioteca de compatibilidad de Android. Sin embargo, por lo general, querrás personalizar el tema para que se ajuste a la marca de tu app. La mejor manera de hacerlo es extender estos estilos de la biblioteca de compatibilidad y anular algunos de los atributos, como se describe en la siguiente sección.

Jerarquía de estilos

Android ofrece una variedad de formas para configurar atributos en toda tu app para Android. Por ejemplo, puedes configurar atributos directamente en un diseño, aplicar un estilo a una vista, aplicar un tema a un diseño o incluso configurar atributos de forma programática.

Cuando elijas cómo diseñar tu app, ten en cuenta la jerarquía de estilos de Android. En general, debes usar temas y estilos tanto como sea posible para mantener la coherencia. Si especificaste los mismos atributos en varios lugares, la siguiente lista determina qué atributos se aplican finalmente. La lista está ordenada de mayor a menor prioridad:

  1. Aplicación de estilo a nivel de carácter o párrafo a través de intervalos de texto a clases derivadas de TextView
  2. Aplicación de atributos de forma programática
  3. Aplicación de atributos individuales directamente a una vista
  4. Aplicación de un estilo a una vista
  5. Estilo predeterminado
  6. Aplicación de un tema a una colección de vistas, una actividad o toda tu app
  7. Aplicación de un estilo determinado específico de la vista, como la configuración de un TextAppearance en un TextView

Figura 2: El estilo de un span anula el estilo de un textAppearance

Si intentas diseñar el estilo de tu app y no ves los resultados que esperas, es probable que otro estilo esté anulando tus cambios. Por ejemplo, si aplicas un tema a tu app, junto con un estilo a un View individual, los atributos de estilo anularán cualquier atributo de tema coincidente para ese View. Sin embargo, ten en cuenta que se seguirá usando cualquier atributo de tema que el estilo no anule.

TextAppearance

Una limitación es que puedes aplicar un solo estilo a un View. Sin embargo, en un TextView también puedes especificar un atributo TextAppearance que funciona de manera similar a un estilo, como se muestra en el siguiente ejemplo:

    <TextView
        ...
        android:textAppearance="@android:style/TextAppearance.Material.Headline"
        android:text="This text is styled via textAppearance!" />
    

TextAppearance te permite definir un estilo específico del texto y dejar el estilo de un View disponible para otros usos. Sin embargo, ten en cuenta que, si defines cualquier atributo de texto directamente en View o en un estilo, esos valores anularán los valores de TextAppearance.

TextAppearance admite un subconjunto de atributos de estilo que ofrece TextView. Para ver la lista completa de atributos, consulta TextAppearance.

Algunos atributos TextView comunes que no se incluyen son lineHeight[Multiplier|Extra], lines, breakStrategy y hyphenationFrequency. TextAppearance funciona a nivel de caracteres y no a nivel de párrafo, por lo que no se admiten atributos que afecten a todo el diseño.

Personaliza el tema predeterminado

Cuando crees un proyecto con Android Studio, aplica un tema de material design a tu app de forma predeterminada, como se define en el archivo styles.xml de tu proyecto. Este estilo AppTheme extiende un tema de la biblioteca de compatibilidad e incluye anulaciones para los atributos de color que usan los elementos de IU clave, como la barra de aplicaciones y el botón de acción flotante (si se usan). Para que puedas personalizar rápidamente el diseño del color de tu app, actualiza los colores proporcionados.

Por ejemplo, tu archivo styles.xml debería ser similar a esto:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
    

Ten en cuenta que los valores de estilo en realidad son referencias a otros recursos de color, definidos en el archivo res/values/colors.xml del proyecto. Así que ese es el archivo que debes editar para cambiar los colores. Sin embargo, antes de comenzar a cambiar estos colores, obtén una vista previa de tus colores con la herramienta Material Color. Esta herramienta te ayuda a elegir colores de la paleta de materiales y obtener una vista previa de cómo se verán en una app.

Cuando conozcas tus colores, actualiza los valores en res/values/colors.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!--   color for the app bar and other primary UI elements -->
        <color name="colorPrimary">#3F51B5</color>

        <!--   a darker variant of the primary color, used for
               the status bar (on Android 5.0+) and contextual app bars -->
        <color name="colorPrimaryDark">#303F9F</color>

        <!--   a secondary color for controls like checkboxes and text fields -->
        <color name="colorAccent">#FF4081</color>
    </resources>
    

Luego, puedes anular cualquier otro estilo que quieras. Por ejemplo, puedes cambiar el color de fondo de la actividad de la siguiente manera:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        ...
        <item name="android:windowBackground">@color/activityBackground</item>
    </style>
    

Para obtener una lista de atributos que puedes usar en tu tema, consulta la tabla de atributos en R.styleable.Theme. Cuando agregues estilos para las vistas en tu diseño, también puedes encontrar atributos mirando la tabla "Atributos XML" en las referencias de clases de vistas. Por ejemplo, todas las vistas admiten atributos XML desde la clase View base.

La mayoría de los atributos se aplican a tipos específicos de vistas, mientras que algunos se aplican a todas las vistas. Sin embargo, algunos atributos de tema enumerados en R.styleable.Theme se aplican a la ventana de actividad, no a las vistas en el diseño. Por ejemplo, windowBackground cambia el fondo de la ventana y windowEnterTransition define una animación de transición para usar cuando comienza la actividad (para obtener más detalles, consulta Cómo iniciar una actividad con una animación).

La biblioteca de compatibilidad de Android también ofrece otros atributos que puedes usar para personalizar tu tema extendido de Theme.AppCompat (como el atributo colorPrimary que se muestra arriba). Estos atributos se ven mejor en el archivo attrs.xml de la biblioteca

Nota: Los nombres de los atributos de la biblioteca de compatibilidad no usan el prefijo android:. Eso se usa solamente para atributos del marco de trabajo de Android.

También hay diferentes temas disponibles en la biblioteca de compatibilidad que quizás quieras extender en vez de los que se muestran arriba. El mejor lugar para ver los temas disponibles es el archivo themes.xml de la biblioteca.

Agrega estilos específicos de una versión

Si una nueva versión de Android agrega atributos de tema que deseas usar, puedes agregarlos a tu tema sin que dejen de ser compatibles con versiones anteriores. Todo lo que necesitas es otro archivo styles.xml guardado en un directorio values que incluya el calificador de versión del recurso. Por ejemplo:

    res/values/styles.xml        # themes for all versions
    res/values-v21/styles.xml    # themes for API level 21+ only
    

Debido a que los estilos del archivo values/styles.xml están disponibles para todas las versiones, tus temas en values-v21/styles.xml pueden heredarlos. Así, puedes evitar duplicar estilos comenzando con un tema "base" y, luego, extenderlo en los estilos específicos de tu versión.

Por ejemplo, si deseas declarar transiciones de ventana para Android 5.0 (API nivel 21) y versiones posteriores, debes usar algunos atributos nuevos. Tu tema base en res/values/styles.xml podría verse así:

    <resources>
        <!-- base set of styles that apply to all versions -->
        <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
            <item name="colorPrimary">@color/primaryColor</item>
            <item name="colorPrimaryDark">@color/primaryTextColor</item>
            <item name="colorAccent">@color/secondaryColor</item>
        </style>

        <!-- declare the theme name that's actually applied in the manifest file -->
        <style name="AppTheme" parent="BaseAppTheme" />
    </resources>
    

Luego, agrega los estilos específicos de la versión en res/values-v21/styles.xml de la siguiente manera:

    <resources>
        <!-- extend the base theme to add styles available only with API level 21+ -->
        <style name="AppTheme" parent="BaseAppTheme">
            <item name="android:windowActivityTransitions">true</item>
            <item name="android:windowEnterTransition">@android:transition/slide_right</item>
            <item name="android:windowExitTransition">@android:transition/slide_left</item>
        </style>
    </resources>
    

Ahora, puedes aplicar AppTheme en tu archivo de manifiesto y el sistema selecciona los estilos disponibles para cada versión del sistema.

A fin de obtener más información sobre el uso de recursos alternativos para diferentes dispositivos, consulta Cómo proveer recursos.

Personaliza estilos de widget

Cada widget del marco de trabajo y la biblioteca de compatibilidad tiene un estilo predeterminado. Por ejemplo, cuando diseñas tu app con un tema de la biblioteca de compatibilidad, una instancia de Button se diseña usando el estilo Widget.AppCompat.Button. Si deseas aplicar un estilo de widget diferente a un botón, puedes hacerlo con el atributo style de tu archivo de diseño. Por ejemplo, lo siguiente aplica el estilo de botón sin bordes de la biblioteca:

    <Button
        style="@style/Widget.AppCompat.Button.Borderless"
        ... />
    

Si deseas aplicar este estilo a todos los botones, puedes declararlo en el buttonStyle de tu tema de la siguiente manera:

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="buttonStyle">@style/Widget.AppCompat.Button.Borderless</item>
        ...
    </style>
    

También puedes extender los estilos de los widgets, como se extiende cualquier otro estilo, y luego aplicar el estilo de widget personalizado en tu diseño o tema.

Para descubrir todos los estilos de widgets alternativos disponibles en la biblioteca de compatibilidad, consulta la referencia R.style para los campos que comienzan con Widget. (Ignora los estilos que comienzan con Base_Widget). Recuerda reemplazar todos los guiones bajos por puntos cuando uses el nombre del estilo en tus recursos.