Cómo oscurecer contenido web en WebView

En Android 10 y versiones posteriores, una app puede admitir una Tema oscuro y cambia automáticamente entre los temas claro y oscuro de la app según el tema del sistema. Para hacer coincidir el tema actual de la app, contenido web en WebView también puedes usar un estilo claro, oscuro o predeterminado.

El comportamiento de WebView interopera con el prefers-color-scheme y color-scheme los estándares de la Web. Siempre que sea posible, si creas el contenido web que deseas para mostrar tu app en WebView, debes definir un tema oscuro para tu sitio web y implementa prefers-color-scheme para que WebView pueda coincidir con el al tema de tu app.

En la siguiente tabla, se describe cómo WebView procesa el contenido web en tu app: según el estilo del contenido web y las condiciones de tu aplicación:

Condiciones de la app Contenido web que usa prefers-color-scheme Contenido web que no usa prefers-color-scheme
La app está usando un tema claro con isLightTheme Se establece en true o no se establece. WebView renderiza el contenido con el tema claro que que haya definido el autor del contenido. WebView renderiza el contenido con el estilo predeterminado definido por la autor del contenido.
La aplicación está usando Forzar oscuro a aplican algorítmicamente un tema oscuro a la app. WebView renderiza el contenido con el tema oscuro que que haya definido el autor del contenido. Si el autor del contenido lo permite, WebView lo renderiza con una tema oscuro que se genera con un algoritmo.
La app está usando un tema oscuro con isLightTheme se establece en false y la app no permite algoritmos oscurecimiento para WebView. WebView renderiza el contenido con el tema oscuro que que haya definido el autor del contenido. WebView renderiza el contenido con el estilo predeterminado definido por la autor del contenido.
La app está usando un tema oscuro con isLightTheme Se establece en false y la app permite oscurecimiento algorítmico para WebView. WebView renderiza el contenido con el tema oscuro que que haya definido el autor del contenido. Si el autor del contenido lo permite, WebView lo renderiza con una tema oscuro que se genera con un algoritmo.

Estilos de autor del contenido

La imagen Atributo isLightTheme indica si el tema de la app es oscuro o claro. WebView siempre establece prefers-color-scheme según isLightTheme. Si isLightTheme es true o no se especifica, entonces prefers-color-scheme es light; De lo contrario, es dark

Esto significa que, si el contenido web usa prefers-color-scheme y el contenido el autor lo permite, ya sea el tema oscuro o claro definido por el autor del contenido siempre se aplica automáticamente al contenido web para que coincida con el tema de la app.

Oscurecimiento algorítmico

Para cubrir los casos en los que no se utiliza el contenido web prefers-color-scheme: tu app puede permitir que WebView, cuando sea necesario, aplique algorítmico al contenido web que renderiza.

Si tu app usa el nivel de la app Forzar el modo oscuro para que se aplique algorítmico aplicar un tema oscuro a tu app, consulta la siguiente sección en la que se describe cómo Permite el oscurecimiento algorítmico para el contenido web con Forzar oscuro.

Si la app no usa esta función, cómo especifica cuándo se permite el oscurecimiento algorítmico en WebView depende del comportamiento nivel de API objetivo. Consulta las siguientes secciones para obtener información sobre apps que se orientan a Android 13 o versiones posteriores y apps orientadas a Android 12 o versiones anteriores para obtener más detalles.

Permitir el oscurecimiento algorítmico para el contenido web con Forzar oscuro

Si tu app usa el nivel de la app Forzar oscuro: Se aplica WebView. oscurecimiento algorítmico del contenido web si se cumplen las siguientes condiciones:

  • WebView y sus elementos superiores permiten forzar el modo oscuro.
  • El tema de la actividad actual se marca como claro con isLightTheme se estableció en true
  • El autor del contenido web no inhabilita explícitamente el oscurecimiento.
  • En el caso de las apps orientadas a Android 13 (nivel de API 33) o versiones posteriores, el contenido web no usa prefers-color-scheme.
  • En el caso de las apps orientadas a Android 12 (nivel de API 32) o versiones anteriores, la app estableció Configuración de forceDarkMode de WebView a FORCE_DARK_AUTO y configuró su estrategia Force Dark para DARK_STRATEGY_USER_AGENT_DARKENING_ONLY

WebView y todos sus elementos superiores pueden permitir forzar el modo oscuro con View.setForceDarkAllowed() El valor predeterminado se toma del atributo setForceDarkAllowed() del Tema de Android, que también debe establecerse en true

La función para forzar el modo oscuro se proporciona principalmente para ofrecer retrocompatibilidad en apps que no proporcionan su propio tema oscuro. Si tu app usa Forzar oscuro, te recomendamos agregar compatibilidad con un tema oscuro.

Permitir el oscurecimiento algorítmico (apps orientadas a Android 13 o versiones posteriores)

Para las apps que no usan la función Forzar oscuro a nivel de la app y se orientan a Android 13 (nivel de API) 33) o versiones posteriores, usa AndroidX setAlgorithmicDarkeningAllowed() y pasa true para especificar que un WebView debe permitir la autenticación oscurecimiento. Este método es retrocompatible con versiones anteriores de Android versiones.

Luego, WebView aplica oscurecimiento algorítmico si se cumplen las siguientes condiciones:

  • El contenido web no usa prefers-color-scheme.
  • El autor del contenido web no inhabilita explícitamente el oscurecimiento.

Permitir el oscurecimiento algorítmico (apps orientadas a Android 12 o versiones anteriores)

En el caso de las apps que no usan la función Forzar oscuro a nivel de la app y se orientan a Android 12 (nivel de API), 32) o versiones anteriores, utiliza FORCE_DARK_ON para permitir el oscurecimiento algorítmico.

Usa FORCE_DARK_ON junto con FORCE_DARK_OFF si tu app proporciona su propio método para alternar entre los temas claro y oscuro, como un elemento que se puede activar o desactivar en la IU o una selección automática basada en el tiempo.

Para comprobar si la función es compatible, agrega las siguientes líneas de código Dondequiera que configures tu objeto WebView, como en Activity.onCreate:

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    WebSettingsCompat.setForceDark(...)
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    WebSettingsCompat.setForceDark(...);
}

Si tu app depende de la detección de cambios en las preferencias del sistema, debe escuchar de forma explícita los cambios de tema y aplicarlos a WebView con Estados FORCE_DARK_ON y FORCE_DARK_OFF.

En el siguiente fragmento de código, se muestra cómo cambiar el formato del tema:

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
        Configuration.UI_MODE_NIGHT_YES -> {
            WebSettingsCompat.setForceDark(myWebView.settings, FORCE_DARK_ON)
        }
        Configuration.UI_MODE_NIGHT_NO, Configuration.UI_MODE_NIGHT_UNDEFINED -> {
            WebSettingsCompat.setForceDark(myWebView.settings, FORCE_DARK_OFF)
        }
        else -> {
            //
        }
    }
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    switch (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) {
        case Configuration.UI_MODE_NIGHT_YES:
            WebSettingsCompat.setForceDark(myWebView.getSettings(), FORCE_DARK_ON);
            break;
        case Configuration.UI_MODE_NIGHT_NO:
        case Configuration.UI_MODE_NIGHT_UNDEFINED:
            WebSettingsCompat.setForceDark(myWebView.getSettings(), FORCE_DARK_OFF);
            break;
    }
}

Cómo personalizar el manejo del tema oscuro

También puedes usar API de ForceDarkStrategy en AndroidX para controlar cómo se aplica el oscurecimiento a un WebView determinado. Esta API es solo se aplica si la opción forzar el modo oscuro está configurada en FORCE_DARK_ON o FORCE_DARK_AUTO.

Con la API, tu app puede usar el oscurecimiento del tema web o el usuario-agente oscurecimiento:

  • Oscurecimiento del tema web: Los desarrolladores web podrían aplicar @media (prefers-color-scheme: dark) para controlar la apariencia de las páginas web en el modo oscuro. WebView procesa el contenido de acuerdo con esta configuración. Para obtener más información sobre oscurecimiento del tema web, consulta la specification.
  • Oscurecimiento de usuario-agente: WebView invierte automáticamente los colores de la Web. . Si usas oscurecimiento de usuario-agente, La consulta @media (prefers-color-scheme: dark) se evalúa como false.

Para elegir entre las dos estrategias, usa la siguiente API:

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    WebSettingsCompat.setForceDarkStrategy(...)
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    WebSettingsCompat.setForceDarkStrategy(...);
}

Las opciones de estrategia admitidas son las siguientes:

  • DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING Esta es la opción predeterminada. Si bien la mayoría de los navegadores tratan Etiqueta <meta name="color-scheme" content="dark light"> como opcional, Android El modo predeterminado de WebView requiere que la metaetiqueta cumpla con la política de la página prefers-color-scheme consultas de medios. Puedes usar componentes WebView DARK_STRATEGY_WEB_THEME_DARKENING_ONLY en cuyo caso WebView siempre aplica consultas de medios incluso si la etiqueta está omitido.

    Sin embargo, recomendamos que los desarrolladores web agreguen <meta name="color-scheme" content="dark light"> etiqueta en sus sitios web para asegúrate de que el contenido se procese correctamente en WebViews con el configuración predeterminada.

  • DARK_STRATEGY_USER_AGENT_DARKENING_ONLY Se llama "oscurecimiento usuario-agente", WebView ignora cualquier oscurecimiento de la página web y aplica oscurecimiento automático.

Si tu app muestra contenido web de origen que personalizaste con el prefers-color-scheme búsqueda de medios, recomendada DARK_STRATEGY_WEB_THEME_DARKENING_ONLY para asegurarte de que WebView use el tema personalizado.

Para ver un ejemplo de tema oscuro aplicado, consulta la Demostración de WebView en GitHub