Cómo agregar color dinámico a tu app

1. Antes de comenzar

En este codelab, actualizarás la app de partida, una app de calculadora de propinas para usar las nuevas funciones de Material Design 3, lo que permite que la interfaz de usuario de una aplicación tenga un tema dinámico según el fondo de pantalla del usuario. A continuación, se muestran algunas capturas de pantalla de la aplicación con colores dinámicos aplicados. También analizarás algunas situaciones adicionales que te permitirán controlar cómo se aplican los colores.

Requisitos previos

Los desarrolladores deben

  • Conocer los conceptos básicos de los temas en Android
  • Sentirse a gusto con la modificación del tema de una app

Qué aprenderás

  • Cómo diferenciar entre los componentes existentes de Material y los temas de Material 3
  • Cómo actualizar un tema a Material 3
  • Cómo crear temas con nuestras herramientas y aplicarlos
  • Cómo se relacionan entre sí los atributos del tema

Requisitos

2. Descripción general de la app de partida

La app de Tip Time es una app para calcular propinas que ofrece opciones para personalizar la propina. Es una de las apps de ejemplo de nuestro curso de capacitación Aspectos básicos de Android en Kotlin.

59906a9f19d6b804.png

3. Cómo actualizar dependencias de Gradle

Antes de actualizar el tema real y aplicar un color dinámico, debes realizar algunos cambios en el archivo build.gradle de tu aplicación.

En la sección de dependencias, asegúrate de que la biblioteca de material sea 1.5.0-alpha04 o una versión posterior:

dependencies {
    // ...
    implementation 'com.google.android.material:material:<version>'
}

En la sección de Android, cambia compileSdkVersion y targetSdkVersion.

hasta 31 o una versión posterior:

android {
    compileSdkVersion 31
    // ...

    defaultConfig {
        // ...
        targetSdkVersion 31
    }
}

En estas instrucciones, se da por sentado que se trata de una app con dependencias relativamente recientes. En el caso de una app que todavía no usa Material o una versión anterior, consulta las instrucciones en la documentación de introducción de los componentes de Material Design para Android.

Dondequiera que hayas creado tus temas, cambia las referencias de Theme.MaterialComponents.* a Theme.Material3.*. Algunos estilos aún no tienen un estilo nuevo en el espacio de nombres de Material3, pero la mayoría de los componentes heredarán el estilo nuevo una vez que el tema superior se actualice a Theme.Material3.*. A continuación, podemos ver que los botones ahora adoptan los nuevos temas redondeados.

En el archivo de temas a continuación, lo único que se cambió es el tema superior. Reemplazaremos este tema por completo en un momento. Algunos de los atributos de color quedaron obsoletos, y algunos de los estilos personalizados que creamos ahora son estándar en Material 3, pero queríamos que tuvieras

themes.xml

<style name="Theme.TipTime" parent="Theme.Material3.Light">
   <!-- Primary brand color. -->
   <item name="colorPrimary">@color/green</item>
   <item name="colorPrimaryVariant">@color/green_dark</item>
   <item name="colorOnPrimary">@color/white</item>
   <!-- Secondary brand color. -->
   <item name="colorSecondary">@color/blue</item>
   <item name="colorSecondaryVariant">@color/blue_dark</item>
   <item name="colorOnSecondary">@color/black</item>
   <!-- Status bar color. -->
   <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
   <!-- For text input fields -->
   <item name="textInputStyle">@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
   <!-- For radio buttons -->
   <item name="radioButtonStyle">@style/Widget.TipTime.CompoundButton.RadioButton</item>
   <!-- For switches -->
   <item name="switchStyle">@style/Widget.TipTime.CompoundButton.Switch</item>
</style>

f91e2acbac7cd469.png

4. Cómo comprender los temas de color y los roles de color

El sistema de colores de Material 3 usa un enfoque organizado para aplicar colores a tu IU. Aún están en uso varios atributos de Theme.AppCompat. Sin embargo, se agregaron más atributos en Theme.MaterialComponents.* y aún más en Theme.Material3.*, por lo que es importante examinar todas las pantallas de tu app para asegurarte de que ninguna propiedad sin implementar se transfiera desde el tema base.

Información sobre los roles de color

Hay más de veinte atributos relacionados con el color en un tema de Material 3. Esto puede parecer abrumador al principio, pero realmente hay algunos colores clave que se combinan con las mismas funciones de 4 a 5 colores para crear colores derivados.

Estos grupos de colores son:

  • Principal (el color principal de la app)
  • Secundario, el color secundario de la app
  • Terciario: puede ser un tercer color complementario al primario y al secundario
  • Error, se usa para el texto y los diálogos de error
  • Información general
  • Surface, SurfaceVariant, Surface Inverse

Los roles son los siguientes: Principal, Secundaria, Terciaria y Error:

<color base>

El color base

activada<color base>

el color de los íconos y el texto que aparecen en el color base

<color base>Contenedor

se derivan de la base, el color, que se usa para botones, diálogos, etc.

on<color base>Contenedor

el color de los íconos y el texto en el contenedor

Por ejemplo, un botón de acción flotante con estilo predeterminado en Material 3 usa Primary como su color base, por lo que usa primaryContainer para el color de fondo del botón y onPrimaryContainer para su contenido.

Cuando personalizas un tema a mano, como mínimo, debes verificar que el atributo on<base color> de cada color base que cambies siga siendo legible.

Las prácticas recomendadas serían ajustar todos los roles en un grupo de color al mismo tiempo para garantizar que no haya artefactos desde la base hasta tu app.

Los colores base de fondo y de superficie suelen tener dos roles: el color base en sí y on<base color> para los íconos o el texto que aparecen sobre él.

5. Cómo crear un tema de Material 3 con Material Theme Builder

Material Theme Builder facilita la compilación de un esquema de colores personalizado, usa su exportación de código integrada para migrar al sistema de colores de M3 y aprovechar el color dinámico. Más información en material.io/material-theme-builder

El tema de la app de Tip Time contiene varios estilos para los componentes, sin embargo, la mayoría de los estilos son predeterminados en los temas de Material 3. Los únicos dos colores clave de los que debemos preocuparnos son primario y secundario.

Estos corresponden a un color primario verde (#1B5E20) y un color secundario azul (#0288D1).

Puedes ingresar esos colores en Material Theme Builder y exportar un tema completo (suponiendo un vínculo a una descripción general completa en otro lugar).

Ten en cuenta que los colores que ingreses pueden cambiar de tono para adaptarse al algoritmo de generación de colores y garantizar colores complementarios y legibles.

A continuación, se muestra un subconjunto de los valores generados cuando ingresas colores personalizados.

7f6c5a33f5233811.png

6. Cómo trabajar con archivos de exportación de Material Theme Builder

El archivo de exportación contiene valores y directorios values-night/ con su propio archivo themes.xml, que corresponde a los temas claro y oscuro. Todos los colores se definen en values/colors.xml.

f66a64db2989a260.png

Los archivos se pueden copiar tal como están, pero deberás cambiar el nombre del tema (AndroidManifest.xml) o en los archivos de tema para que coincidan. El nombre predeterminado de las herramientas es AppTheme.

Reinicia la app. Se verá casi igual. Un cambio notable son los Switch y RadioButtons, cuyos estados seleccionados ahora tienen un tema con tonos del color primario en comparación con los colores secundarios. En aplicaciones más grandes, es posible que debas repasar algunos diseños.

38a50ada47fd5ea4.png

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.tiptime">

   <application ...>
       <activity android:name=".MainActivity"
           android:exported="true">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>
   </application>

</manifest>

7. Agrega un color dinámico

Con un tema de Material 3 adecuado en uso, podemos hacer que la IU sea dinámica con algunas pequeñas adiciones.

La API de Dynamic Colors te permite aplicar colores dinámicos a todas las actividades.

en una app, actividades individuales o vistas o fragmentos individuales. Para

aplicaremos colores dinámicos a nivel global.

Crea un archivo de clase Application

class TipTimeApplication: Application() {
    override fun onCreate() {
        // Apply dynamic color
        DynamicColors.applyToActivitiesIfAvailable(this)
    }
}

Necesitamos hacer referencia a este archivo recién creado en el manifiesto de Android:

AndroidManifest.xml

< application android name=".TipTimeApplication
<!--- Other existing attributes –>

</application >

En los sistemas Android 12 y versiones posteriores, se examina el papel de pared del usuario para el esquema predeterminado) a fin de generar varias paletas tonales. Los valores de estas paletas se usan para crear un ThemeOverlay.

La clase DynamicColors registra un elemento ActivityLifecycleCallbacks que intercepta en ActivityPreCreated para aplicar la superposición de temas dinámicos creada por el sistema o uno que hayas proporcionado.

eba71f96f4ba9cdf.png

8. Cómo aplicar una superposición de temas personalizados

Nuestras herramientas pueden exportar superposiciones de temas, pero también puedes crearlas manualmente si anulas una pequeña cantidad de atributos.

Una superposición de temas está diseñada para usarse junto con otro tema y solo proporciona los valores que se cambiarán sobre el tema base.

Supongamos que por alguna razón, tal vez para las marcas, necesitamos que los tonos de color primario sean tonos de rojo. Podríamos hacerlo con los siguientes archivos y atributos.

colors.xml

<resources>
    <color name="overlay_light_primary">#9C4146</color>
    <color name="overlay_light_onPrimary">#FFFFFF</color> 
    <color name= "overlay_light_primaryContainer">#FFDADB</color>
    <color name="overlay_light_onPrimaryContainer">#400008</color>
</resources >

themes_overlays.xml

<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.Light">
    <item name="colorPrimary">@color/overlay_light_primary</item>
    <item name="colorOnPrimary">@color/overlay_light_onPrimary</item> 
    <item name="colorPrimaryContainer">@color/overlay_light_primaryContainer</item> 
    <item name="colorOnPrimaryContainer">@color/overlay_light_onPrimaryContainer<item>
</style>

Para el código anterior, Android 12 aplicará un tema claro dinámico y superpondrá tus cambios. Como alternativa, puedes usar cualquier ThemeOverlay válido como elemento superior, incluidos cualquiera de los siguientes:

ThemeOverlay.Material3.Light

ThemeOverlay.Material3.Dark

ThemeOverlay.Material3.DayNight ThemeOverlay.Material3.DynamicColors.Dark

ThemeOverlay.Material3.DynamicColors.DayNight

Para usar esta superposición de temas en lugar del valor predeterminado de Material, cambia la llamada a DynamicColors.applyToActivitiesIfAvailable de la siguiente manera:

DynamicColors.applyToActivitiesIfAvailable(this, R.style.AppTheme_Overlay)

d87020776782036f.png

9. Cómo agregar color dinámico a los atributos personalizados

Hasta ahora, anulamos las propiedades que ya existen en un tema de Material 3. Tenemos otro posible caso en color dinámico en el que podemos tener uno o más atributos personalizados que deban asignarse.

Cuando una app habilita el color dinámico, obtiene acceso a 5 paletas tonales: tres paletas de acentos y dos paletas neutras con los siguientes roles aproximados:

system_accent1

Tonos de color primarios

system_accent2

Tonos de color secundarios

system_accent3

Tonos de color terciarios

system_neutral1

Fondos y superficies neutrales

system_neutral2

Superficies y contornos neutros

Cada paleta tiene varios pasos tonales que van desde el blanco

a negro: 0, 10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000.

Al diseñar una IU para color dinámico, debes pensar menos en el color específico y más en la relación del tono y la luminancia de ese componente con otros en el sistema de diseño.

Supongamos que quieres que los íconos tengan un tema con la paleta de elementos destacados secundaria y agregaste un atributo para ajustar el tono de los íconos con la siguiente entrada en attrs.xml.

attrs.xml

<resources>
    <attr name="iconColor" format="color" />
</resources>

Tu superposición de temas podría verse de la siguiente manera:

<style name="AppTheme.Overlay" parent="ThemeOverlay.Material3.DynamicColors.DayNight"> 
<item name="iconColor">@android:color/system_accent2_600</item>
</style>

Cuando reinstales la app y cambies el fondo de pantalla, la app adoptará esa paleta secundaria.

11ef0035702640d9.png

264b2c2e74c5f574.png

Estas paletas son específicas de Android 12 (nivel de API 31), por lo que deberás colocar los archivos relevantes en carpetas con un sufijo -v31, a menos que tu app tenga un SDK mínimo establecido en 31 o una versión posterior.

10. Resumen

En este codelab, pudiste hacer lo siguiente:

  • Agrega dependencias para actualizar tu tema a Material 3.
  • Comprende los nuevos grupos de colores y roles.
  • Comprende cómo migrar de un tema estático a un color dinámico.
  • Aprende a usar superposiciones de temas y colores dinámicos para atributos de temas personalizados.