【问题标题】:WebView resetting UiMode and breaking dark themeWebView 重置 UiMode 并打破黑暗主题
【发布时间】:2019-08-15 20:37:49
【问题描述】:

我们的应用依赖 AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) 来让我们从 values/colorsvalues-night/colors 中选择 Light 和 Dark 主题颜色

但每次我们尝试使用 WebView 时,它都会从重置 UiMode 开始,我们的应用会混淆为我们的主题选择哪些颜色值

有人详细讨论了这个问题herehere

有人遇到过类似的问题吗?

【问题讨论】:

    标签: android android-webview android-theme android-dark-theme


    【解决方案1】:

    回答我自己的问题,看起来谷歌解决了这个问题https://issuetracker.google.com/issues/37124582

    https://developer.android.com/jetpack/androidx/releases/appcompat#1.1.0-alpha03Fixed WebView resets DayNight Resources

    【讨论】:

    • 1.1.0-alpha 在使用旧版本 Android System WebView 的设备上也崩溃了——在 API 21 到 23 (OS5,6) 等设备/模拟器上。以下是我如何绕过stackoverflow.com/a/58190021/2344192
    • 是的,我看到了,也以这种方式实现了它。可悲的是,我正在使用一个外部 sdk,它也崩溃了,我无法修复它:/ 必须等待他们发​​布修复版本
    【解决方案2】:

    由于上一期已关闭,我打开了新一期: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
                )
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      首先你需要在你的项目中添加 android.webkit 依赖

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

      在撰写本文时,最新的稳定版 webkit 是 1.3.0。 值得注意的是,在 1.2.0 版本中已经添加了 Dark Theme 支持,在此版本之前,Webview 无法添加 Dark Theme 支持。

      下一步是检查用户设备上的 Webview 和 Android 框架是否支持主题化:

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

      请注意,WebViewFeature.FORCE_DARK 仅从 Webview 版本 76 开始受支持。不幸的是,在该版本之前,没有直接的方法来支持黑暗主题。 如果您拥有 Web 视图中显示的内容,您可能希望实现自定义 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-06
        • 1970-01-01
        相关资源
        最近更新 更多