Затемнять веб-контент в WebView

В Android 10 и более поздних версиях приложение может поддерживать тёмную тему и автоматически переключаться между светлой и тёмной темами в зависимости от системных настроек. Чтобы соответствовать текущей теме приложения, веб-контент в WebView также может использовать светлый, темный или стандартный стиль.

Поведение WebView соответствует веб-стандартам prefers-color-scheme и color-scheme. Если вы создаете веб-контент, который хотите показывать в WebView, по возможности определите тёмную тему для своего сайта и реализуйте prefers-color-scheme, чтобы WebView мог сопоставить тему веб-контента с темой вашего приложения.

В таблице ниже описано, как WebView отрисовывает веб-контент в приложении в зависимости от стиля контента и условий приложения.

Фильтры приложений Веб-контент, в котором используется prefers-color-scheme Веб-контент, в котором не используется prefers-color-scheme
В приложении используется светлая тема, а для параметра isLightTheme задано значение true или не задано никакое значение. WebView отображает контент со светлой темой, которую определил автор контента. WebView отображает контент со стилем по умолчанию, заданным автором контента.
В приложении используется автоматическая тёмная тема, которая применяется алгоритмически. WebView отображает контент в тёмной теме, которую определил автор контента. Если автор контента разрешил это, WebView показывает контент в тёмной теме, которая генерируется с помощью алгоритма.
Приложение использует тёмную тему, для isLightTheme задано значение false, и в приложении не разрешено алгоритмическое затемнение для WebView. Компонент WebView отрисовывает контент с тёмной темой, которую определил автор контента. WebView отображает контент со стилем по умолчанию, заданным автором контента.
В приложении используется тёмная тема, для isLightTheme задано значение false, и приложение разрешает алгоритмическое затемнение для WebView. Компонент WebView отрисовывает контент с тёмной темой, которую определил автор контента. Если автор контента разрешил это, WebView показывает контент в тёмной теме, которая генерируется с помощью алгоритма.

Стили, заданные автором контента

Атрибут isLightTheme указывает, какая тема используется в приложении – светлая или тёмная. WebView всегда задает prefers-color-scheme в соответствии с isLightTheme. Если для параметра isLightTheme задано значение true или не задано никакое значение, то для параметра prefers-color-scheme задается значение light, в противном случае – dark.

Это означает, что если веб-контент использует prefers-color-scheme и автор контента разрешает это, то светлая или темная тема, определенная автором контента, всегда автоматически применяется к веб-контенту в соответствии с темой приложения.

Алгоритмическое затемнение

Если веб-контент не использует prefers-color-scheme, вы можете разрешить WebView при необходимости применять алгоритм тёмной темы к отображаемому веб-контенту.

Если в вашем приложении используется автоматическая тёмная тема на уровне приложения, ознакомьтесь с разделом Как разрешить автоматическое затемнение веб-контента.

Если в приложении не используется автоматическая тёмная тема, то способ, которым вы указываете, когда разрешать алгоритмическое затемнение в WebView, зависит от целевого уровня API приложения. Подробную информацию вы найдете в разделах ниже: Приложения, предназначенные для Android 13 или более поздней версии и Приложения, предназначенные для Android 12 или более ранней версии.

Разрешить алгоритмическое затемнение веб-контента с помощью автоматической тёмной темы

Если в приложении используется автоматическая тёмная тема на уровне приложения, WebView применяет алгоритмическое затемнение к веб-контенту при соблюдении следующих условий:

  • Компонент WebView и его родительские элементы поддерживают автоматическую тёмную тему.
  • Текущая тема действия помечена как светлая, а для isLightTheme задано значение true.
  • Автор веб-контента не запретил затемнение.
  • Для приложений, предназначенных для Android 13 (уровень API 33) или более поздней версии, веб-контент не использует prefers-color-scheme.
  • Для приложений, предназначенных для Android 12 (уровень API 32) или более ранней версии: в приложении задана настройка forceDarkMode для WebView со значением FORCE_DARK_AUTO и стратегия автоматической тёмной темы со значением DARK_STRATEGY_USER_AGENT_DARKENING_ONLY.

WebView и все его родительские элементы могут разрешить автоматическую тёмную тему с помощью View.setForceDarkAllowed(). Значение по умолчанию берется из атрибута setForceDarkAllowed() темы Android, которому также должно быть присвоено значение true.

Автоматическая тёмная тема в основном предназначена для обратной совместимости в приложениях, в которых не предусмотрена собственная тёмная тема. Если в вашем приложении используется автоматическая тёмная тема, рекомендуем добавить поддержку тёмной темы.

Разрешить алгоритмическое затемнение (приложения, предназначенные для Android 13 или более поздней версии)

Если в приложении не используется автоматическая тёмная тема на уровне приложения и оно предназначено для Android 13 (уровень API 33) или более поздней версии, используйте метод Jetpack Webkit setAlgorithmicDarkeningAllowed() и передайте true, чтобы указать, что WebView должен разрешать алгоритмическое затемнение. Этот метод обратно совместим с предыдущими версиями Android.

Затем WebView применяет алгоритмическое затемнение, если выполняются следующие условия:

  • Веб-контент не использует prefers-color-scheme.
  • Автор веб-контента не запретил затемнение.

Разрешить алгоритмическое затемнение (приложения для Android 12 или более ранних версий)

Если в приложении не используется автоматическая тёмная тема на уровне приложения и оно предназначено для Android 12 (уровень API 32) или более ранней версии, используйте FORCE_DARK_ON, чтобы разрешить алгоритмическое затемнение.

Используйте FORCE_DARK_ON вместе с FORCE_DARK_OFF, если в вашем приложении есть собственный способ переключения между светлой и тёмной темами, например переключатель в интерфейсе или автоматический выбор на основе времени.

Чтобы проверить, поддерживается ли эта функция, добавьте следующие строки кода в то место, где вы настраиваете объект WebView, например в Activity.onCreate:

Kotlin

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

Java

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

Если ваше приложение зависит от изменений в системных настройках, оно должно отслеживать изменения темы и применять их к WebView с состояниями FORCE_DARK_ON и FORCE_DARK_OFF.

В следующем фрагменте кода показано, как изменить формат темы:

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;
    }
}

Настроить обработку тёмной темы

Вы также можете использовать ForceDarkStrategy API в библиотеке Jetpack, чтобы управлять тем, как затемнение применяется к определенному компоненту WebView. Этот API применим, только если для автоматической тёмной темы задано значение FORCE_DARK_ON или FORCE_DARK_AUTO.

С помощью API ваше приложение может использовать либо затемнение веб-темы, либо затемнение агента пользователя:

  • Затемнение веб-темы. Веб-разработчики могут использовать @media (prefers-color-scheme: dark), чтобы управлять внешним видом веб-страницы в тёмной теме. WebView отрисовывает контент в соответствии с этими настройками. Подробнее о затемнении веб-тем читайте в спецификации.
  • Затемнение агента пользователя. WebView автоматически инвертирует цвета веб-страницы. Если вы используете затемнение агента пользователя, запрос @media (prefers-color-scheme: dark) возвращает значение false.

Чтобы выбрать одну из двух стратегий, используйте следующий API:

Kotlin

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

Java

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

Поддерживаются следующие варианты стратегий:

  • DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: Это вариант по умолчанию. Хотя большинство браузеров считают тег <meta name="color-scheme" content="dark light"> необязательным, в режиме по умолчанию Android WebView требует, чтобы метатег учитывал запросы медиа prefers-color-scheme веб-страницы. Компоненты WebView можно использовать в режиме DARK_STRATEGY_WEB_THEME_DARKENING_ONLY. В этом случае WebView всегда применяет запросы медиа, даже если тег опущен.

    Однако мы рекомендуем веб-разработчикам добавлять на свои сайты тег <meta name="color-scheme" content="dark light">, чтобы контент правильно отображался в компонентах WebView со стандартной конфигурацией.

  • DARK_STRATEGY_USER_AGENT_DARKENING_ONLY: WebView игнорирует затемнение веб-страницы и применяет автоматическое затемнение.

Если в вашем приложении показывается собственный веб-контент, настроенный с помощью медиазапроса prefers-color-scheme, рекомендуем использовать DARK_STRATEGY_WEB_THEME_DARKENING_ONLY, чтобы в WebView применялась пользовательская тема.

Пример применения тёмной темы можно посмотреть в демоверсии WebView на GitHub.