WebView сбрасывает UiMode и ломает темную тему

Наше приложение опирается на AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) чтобы мы подбирали светлые и темные цвета values/colors а также values-night/colors

Но каждый раз, когда мы пытаемся использовать WebView, он начинается с сброса UiMode, и наше приложение запутывается, какие значения цвета выбрать для наших тем

Некоторые люди обсуждали этот вопрос подробно здесь и здесь

Кто-нибудь сталкивался с подобной проблемой?

1 ответ

Поскольку предыдущий выпуск был закрыт, я открыл новый: https://issuetracker.google.com/issues/170328697

И я попытался исправить это так:

class UiModeCareWebView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : WebView(context, attrs, defStyleAttr) {

    init {
        fixUiModeIfNeeded()
    }

    private fun fixUiModeIfNeeded() {
        val configuration = context.resources.configuration
        val configurationNighMode = configuration.uiMode and UI_MODE_NIGHT_MASK
        val appCompatNightMode = getDefaultNightMode()

        val newUiModeConfiguration = when {
            configurationNighMode == UI_MODE_NIGHT_NO && appCompatNightMode == MODE_NIGHT_YES -> {
                UI_MODE_NIGHT_YES or (configuration.uiMode and UI_MODE_NIGHT_MASK.inv())
            }
            configurationNighMode == UI_MODE_NIGHT_YES && appCompatNightMode == MODE_NIGHT_NO -> {
                UI_MODE_NIGHT_NO or (configuration.uiMode and UI_MODE_NIGHT_MASK.inv())
            }
            else -> null
        }

        if (newUiModeConfiguration != null) {
            val fixedConfiguration = Configuration().apply {
                uiMode = newUiModeConfiguration
            }
            @Suppress("DEPRECATION")
            context.resources.updateConfiguration(
                fixedConfiguration,
                context.resources.displayMetrics
            )
        }
    }
}

Отвечая на мой собственный вопрос, похоже, что Google устранил проблему https://issuetracker.google.com/issues/37124582

с https://developer.android.com/jetpack/androidx/releases/appcompat Fixed WebView resets DayNight Resources

Прежде всего вам нужно добавить в свой проект зависимость android.webkit

dependencies {
   implementation "androidx.webkit:webkit:1.3.0"
}

На момент написания этой статьи последняя стабильная версия webkit - 1.3.0. Стоит отметить, что поддержка темной темы была добавлена ​​в версии 1.2.0, до этой версии невозможно было добавить поддержку темной темы в Webview.

Следующим шагом будет проверка, поддерживает ли Webview и Android framework на пользовательском устройстве тематику:

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

Обратите внимание, что WebViewFeature.FORCE_DARKподдерживается только начиная с версии 76 Webview. К сожалению, до этой версии не существовало простого способа поддержки темных тем. Если вы владеете содержимым, отображаемым в Webview, вы можете реализовать свои собственные темы CSS и переключать их с помощью @JavascriptInterface из вашего приложения.

Если WebViewFeature.FORCE_DARK поддерживается, мы можем выбрать один из трех доступных вариантов:

FORCE_DARK_OFF - отключить темную тему, контент будет отображаться в светлой теме по умолчаниюFORCE_DARK_ON - Включить темную тему, контент будет отображаться в темной темеFORCE_DARK_AUTO - Включить темную тему в зависимости от состояния родительского представления Затем нам нужно применить настройку с помощью WebSettingsCompat

WebSettingsCompat.setForceDark(webView.settings, WebSettingsCompat.FORCE_DARK_ON)

Вы можете прочитать об этом более подробно в следующем блоге

https://androidexplained.github.io/ui/android/material-design/2020/09/24/dark-mode-webview.html

Другие вопросы по тегам