Escurecer conteúdo da Web no WebView

No Android 10 e versões mais recentes, um app pode oferecer suporte a um tema escuro e mudar automaticamente entre temas claros e escuros de acordo com o tema do sistema. Para combinar com o tema atual do app, o conteúdo da Web na WebView também pode usar o estilo claro, escuro ou padrão.

O comportamento da WebView interopera com os padrões da Web prefers-color-scheme e color-scheme. Sempre que possível, se você criar o conteúdo da Web que quer que o app mostre na WebView, defina um tema escuro para o site e implemente prefers-color-scheme para que a WebView possa associar o tema do conteúdo da Web ao tema do app.

A tabela a seguir descreve como a WebView renderiza conteúdo da Web no seu app, dependendo do estilo do conteúdo da Web e das condições do app:

Condições do app Conteúdo da Web que usa prefers-color-scheme Conteúdo da Web que não usa prefers-color-scheme
O app está usando um tema claro com isLightTheme definido como true ou sem definição. A WebView renderiza o conteúdo com o tema claro definido pelo autor. A WebView renderiza o conteúdo com o estilo padrão definido pelo autor.
O app está usando o recurso Forçar modo escuro para aplicar algoritmicamente um tema escuro ao app. A WebView renderiza o conteúdo com o tema escuro definido pelo autor. Se o autor do conteúdo permitir, a WebView vai renderizar o conteúdo com um tema escuro gerado usando um algoritmo.
O app está usando um tema escuro com isLightTheme definido como false e não permite o escurecimento algorítmico do WebView. A WebView renderiza o conteúdo com o tema escuro definido pelo autor. A WebView renderiza o conteúdo com o estilo padrão definido pelo autor.
O app está usando um tema escuro com isLightTheme definido como false, e ele permite o escurecimento algorítmico da WebView (link em inglês). A WebView renderiza o conteúdo com o tema escuro definido pelo autor. Se o autor do conteúdo permitir, a WebView vai renderizar o conteúdo com um tema escuro gerado usando um algoritmo.

Estilo do autor do conteúdo

O atributo isLightTheme de um app indica se o tema é claro ou escuro. A WebView sempre define prefers-color-scheme de acordo com isLightTheme. Se isLightTheme for true ou não for especificado, prefers-color-scheme será light. Caso contrário, será dark.

Isso significa que, se o conteúdo da Web usar prefers-color-scheme e o autor permitir, o tema claro ou escuro definido pelo autor será sempre aplicado automaticamente ao conteúdo da Web para corresponder ao tema do app.

Escurecimento algorítmico

Para abranger casos em que o conteúdo da Web não usa prefers-color-scheme, seu app pode permitir que a WebView, quando necessário, aplique um tema escuro ao conteúdo da Web renderizado.

Se o app estiver usando o recurso Forçar modo escuro para aplicar algoriticamente um tema escuro ao app, consulte a seção a seguir, que descreve como permitir o escurecimento algorítmico para conteúdo da Web com o recurso Forçar modo escuro.

Se o app não estiver usando o Forçar modo escuro, a forma como ele especificará quando permitir o escurecimento algorítmico na WebView dependerá do nível desejado da API do app. Consulte as seções abaixo para saber mais detalhes sobre apps destinados ao Android 13 ou versões mais recentes e apps destinados ao Android 12 ou versões anteriores.

Permitir o escurecimento algorítmico de conteúdo da Web com o recurso Forçar modo escuro

Se o app estiver usando o recurso Forçar modo escuro no nível do app, a WebView aplicará o escurecimento algorítmico ao conteúdo da Web se as seguintes condições forem atendidas:

  • O WebView e os elementos pais dele permitem o recurso "Forçar modo escuro".
  • O tema da atividade atual está marcado como claro com isLightTheme definido como true.
  • O autor do conteúdo da Web não desativa explicitamente o escurecimento.
  • Em apps destinados ao Android 13 (nível 33 da API) ou versões mais recentes, o conteúdo da Web não usa prefers-color-scheme.
  • Para apps destinados ao Android 12 (nível 32 da API) ou versões anteriores: o app definiu a configuração forceDarkMode da WebView como FORCE_DARK_AUTO e a estratégia Forçar modo escuro como DARK_STRATEGY_USER_AGENT_DARKENING_ONLY.

A WebView e todos os pais dela podem permitir o uso de escuros à força usando View.setForceDarkAllowed(). O valor padrão é retirado do atributo setForceDarkAllowed() do tema do Android, que também precisa ser definido como true.

Forçar o modo escuro é fornecido principalmente para compatibilidade com versões anteriores em apps que não fornecem o próprio tema escuro. Se seu app usa o recurso Forçar modo escuro, recomendamos adicionar suporte a um tema escuro.

Permitir o escurecimento algorítmico (apps destinados ao Android 13 ou versões mais recentes)

Para apps que não usam o recurso Forçar modo escuro no app e são direcionados ao Android 13 (nível 33 da API) ou versões mais recentes, use o método AndroidX setAlgorithmicDarkeningAllowed() e transmita true para especificar que uma WebView precisa permitir o escurecimento de algoritmos. Esse método tem compatibilidade com versões anteriores do Android.

Em seguida, o WebView aplica o escurecimento algorítmico se as seguintes condições forem atendidas:

  • O conteúdo da Web não usa prefers-color-scheme.
  • O autor do conteúdo da Web não desativa explicitamente o escurecimento.

Permitir o escurecimento algorítmico (apps destinados ao Android 12 ou versões anteriores)

Para apps que não estão usando o Forçar modo escuro no app e são direcionados ao Android 12 (nível 32 da API) ou versões anteriores, use FORCE_DARK_ON para permitir o escurecimento algorítmico.

Use FORCE_DARK_ON com FORCE_DARK_OFF se o app fornecer um método próprio para alternar entre temas claros e escuros, como um elemento alternável na interface ou uma seleção automática baseada em tempo.

Para verificar se o recurso é compatível, adicione as seguintes linhas de código sempre que configurar o objeto WebView, como em Activity.onCreate:

Kotlin

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

Java

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

Se o app depende da detecção de mudanças nas preferências do sistema, ele precisa detectar explicitamente as mudanças de tema e aplicá-las à WebView com os estados FORCE_DARK_ON e FORCE_DARK_OFF.

O snippet de código a seguir mostra como mudar o formato do 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;
    }
}

Personalizar o gerenciamento do tema escuro

Você também pode usar a API ForceDarkStrategy no AndroidX para controlar como o escurecimento é aplicado a um determinado WebView. Essa API será aplicável somente se o recurso "Forçar modo escuro" estiver definido como FORCE_DARK_ON ou FORCE_DARK_AUTO.

Ao usar a API, seu app pode usar o escurecimento do tema da Web ou o escurecimento do user agent:

  • Escurecimento do tema da Web: os desenvolvedores da Web podem aplicar @media (prefers-color-scheme: dark) para controlar a aparência da página da Web no modo escuro. A WebView renderiza o conteúdo de acordo com essas configurações. Para saber mais sobre o escurecimento de temas da Web, consulte a especificação.
  • Escurecimento do user agent: a WebView inverte automaticamente as cores da página da Web. Se você usar o escurecimento do user agent, a consulta @media (prefers-color-scheme: dark) será avaliada como false.

Para escolher entre as duas estratégias, use a seguinte API:

Kotlin

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

Java

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

As opções de estratégia disponíveis são:

  • DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: essa é a opção padrão. Embora a maioria dos navegadores trate a tag <meta name="color-scheme" content="dark light"> como opcional, o modo padrão do Android WebView exige que a metatag atenda às consultas de mídia prefers-color-scheme da página da Web. Você pode usar WebViews com o modo DARK_STRATEGY_WEB_THEME_DARKENING_ONLY. Nesse caso, a WebView sempre aplica consultas de mídia, mesmo que a tag seja omitida.

    No entanto, recomendamos que os desenvolvedores da Web adicionem a tag <meta name="color-scheme" content="dark light"> aos sites para garantir que o conteúdo seja renderizado corretamente em WebViews com a configuração padrão.

  • DARK_STRATEGY_USER_AGENT_DARKENING_ONLY: chamado de "escurecimento do user agent", a WebView ignora qualquer escurecimento de página da Web e aplica o escurecimento automático.

Caso o app mostre conteúdo da Web próprio que você personalizou com a consulta de mídia prefers-color-scheme, recomendamos DARK_STRATEGY_WEB_THEME_DARKENING_ONLY para garantir que a WebView use o tema personalizado.

Para conferir um exemplo de tema escuro aplicado, consulte a demonstração do WebView no GitHub (em inglês).