Cómo implementar el tema oscuro

Prueba hacerlo con Compose
Jetpack Compose es el kit de herramientas de IU recomendado para Android. Obtén información para trabajar con temas en Compose.

Figura 1. Tema oscuro

El Tema oscuro está disponible en Android 10 (nivel de API 29) y versiones posteriores. Tiene los siguientes beneficios:

  • Reduce el consumo de energía en una cantidad significativa, según la tecnología de pantalla del dispositivo.
  • Mejora el nivel de visibilidad para los usuarios con visión reducida y aquellos con sensibilidad a la luz brillante.
  • Facilita el uso de los dispositivos en entornos con poca luz.

El Tema oscuro se aplica a la IU del sistema Android y a las apps que se ejecutan en el dispositivo.

Existen tres formas de habilitar el Tema oscuro en Android 10 y versiones posteriores:

  • Usa la configuración del sistema. Para ello, ve a Configuración > Pantalla > Tema para habilitar el Tema oscuro.
  • Utiliza la tarjeta de Configuración rápida para cambiar de tema desde la bandeja de notificaciones (cuando se habilita la opción).
  • En los dispositivos Pixel, habilita el modo de Ahorro de batería para habilitar el Tema oscuro al mismo tiempo. Es posible que otros dispositivos no admitan este comportamiento.

Si quieres obtener instrucciones para aplicar un tema oscuro a contenido basado en la Web mediante un componente WebView, consulta Cómo oscurecer el contenido web en WebView.

Cómo admitir el Tema oscuro en la app

Para admitir el Tema oscuro, configura el tema de la app (que por lo general se encuentra en res/values/styles.xml) para que herede de un tema DayNight:

<style name="AppTheme" parent="Theme.AppCompat.DayNight">

También puedes usar el tema oscuro de Material Components:

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">

Esto vincula el tema principal de la app con los parámetros de modo nocturno controlados por el sistema y le otorga a la app un Tema oscuro predeterminado cuando está habilitado.

Temas y estilos

Evita usar colores o íconos codificados pensados para usarse con un tema claro. En su lugar, usa atributos de tema o recursos compatibles con modos nocturnos.

Dos atributos de tema son los más importantes para el Tema oscuro:

  • ?android:attr/textColorPrimary: Es un color de texto de uso general. Es casi negro en el tema claro y casi blanco en temas oscuros. Contiene un estado inhabilitado.
  • ?attr/colorControlNormal: Es un color de ícono de uso general. Contiene un estado inhabilitado.

Se recomienda usar componentes de Material Design, ya que su sistema de aplicación de temas de color (como los atributos de tema ?attr/colorSurface y ?attr/colorOnSurface) brinda un acceso fácil a colores adecuados. Puedes personalizar estos atributos en tu tema.

Cómo cambiar temas desde la app

Puedes permitir que los usuarios cambien el tema de la app mientras se está ejecutando. Las siguientes son opciones recomendadas:

  • Luz
  • Oscuro
  • Predeterminado del sistema (la opción predeterminada recomendada)

Estas opciones se asignan directamente a los modos AppCompat.DayNight:

Para cambiar el tema, haz lo siguiente:

Modo oscuro forzado

Android 10 proporciona Modo oscuro forzado, una función que permite a los desarrolladores implementar rápidamente un tema oscuro sin tener que definir de manera explícita un tema DayNight.

Esta función analiza cada vista de tu app con tema claro y aplica un tema oscuro automáticamente antes de que se muestre en la pantalla. Puedes usar una combinación de Modo oscuro forzado y una implementación nativa para reducir el tiempo necesario para implementar el tema oscuro.

Las apps deben habilitar el Modo oscuro forzado estableciendo android:forceDarkAllowed="true" en el tema de la actividad. Este atributo se establece en todos los temas claros proporcionados por AndroidX y el sistema, como Theme.Material.Light. Cuando uses Modo oscuro forzado, prueba tu app exhaustivamente y excluye vistas según sea necesario.

Si la app utiliza un tema oscuro (como Theme.Material), no se aplicará Modo oscuro forzado. De forma similar, si el tema de la app hereda de un tema DayNight, no se aplicará Forzar oscuro debido al cambio de tema automático.

Cómo inhabilitar el modo oscuro forzado en una vista

El Modo oscuro forzado se puede controlar en vistas específicas con el android:forceDarkAllowed atributo de diseño o con setForceDarkAllowed().

Contenido web

Para obtener información sobre el uso de temas oscuros en el contenido basado en la Web, consulta Cómo oscurecer el contenido web en WebView. Para ver un ejemplo de tema oscuro aplicado a un WebView, consulta la demostración de WebView en GitHub .

Prácticas recomendadas

En las siguientes secciones, se proporcionan prácticas recomendadas para implementar temas oscuros.

Notificaciones y widgets

Para las superficies de la IU que muestras en el dispositivo, pero que no controlas directamente, asegúrate de que las vistas que uses reflejen el tema de la app host. Dos ejemplos son las notificaciones y los widgets del selector.

Notificaciones

Usa las plantillas de notificación que proporciona el sistema, como MessagingStyle. Esto significa que el sistema es responsable de aplicar el estilo de vista correcto.

Widgets y vistas de notificaciones personalizadas

Para los widgets del selector, o si tu app usa vistas de contenido de notificaciones personalizadas, prueba el contenido tanto en los temas claros como en los oscuros.

Estos son algunos de los problemas comunes que debes evitar:

  • Suponer que el color de fondo siempre es claro
  • Codificar los colores del texto
  • Configurar un color de fondo codificado mientras se usa el color de texto predeterminado
  • Usar un ícono de diseño que es un color estático

En todos estos casos, usa los atributos de tema apropiados en lugar de colores codificados.

Pantallas de inicio

Si tu app tiene una pantalla de inicio personalizada, es posible que debas modificarla para que refleje el tema seleccionado.

Quita los colores codificados, como los colores de fondo configurados de forma programática en blanco. En su lugar, usa el atributo de tema ?android:attr/colorBackground.

Cambios de configuración

Cuando se cambia el tema de la app (ya sea mediante la configuración del sistema o AppCompat), se activa un uiMode cambio de configuración. Esto significa que las actividades se recrean automáticamente.

En algunos casos, tal vez quieras que una app controle el cambio de configuración. Por ejemplo, si deseas demorar un cambio de configuración porque se está reproduciendo un video.

Una app puede controlar la implementación del Tema oscuro declarando que cada Activity puede controlar el cambio de configuración de uiMode:

<activity
    android:name=".MyActivity"
    android:configChanges="uiMode" />

Si una Activity declara que se ocupa de controlar los cambios de configuración, se llamará a su onConfigurationChanged() método cuando haya un cambio de tema.

Para comprobar cuál es el tema actual, las apps pueden ejecutar un código como el siguiente:

Kotlin

val currentNightMode = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
when (currentNightMode) {
    Configuration.UI_MODE_NIGHT_NO -> {} // Night mode is not active, we're using the light theme.
    Configuration.UI_MODE_NIGHT_YES -> {} // Night mode is active, we're using dark theme.
}

Java

int currentNightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
switch (currentNightMode) {
    case Configuration.UI_MODE_NIGHT_NO:
        // Night mode is not active, we're using the light theme
        break;
    case Configuration.UI_MODE_NIGHT_YES:
        // Night mode is active, we're using dark theme
        break;
}