WebView resetting UiMode and breaking dark theme
Asked Answered
F

3

9

Our app relies on AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) to make us pick up Light and Dark theme colors from values/colors and values-night/colors

But every time we try to use the WebView, it starts by resetting the UiMode and our app gets confused which color values to pick for our themes

Some people discussed the issue in detail here and here

Anyone out there run into a similar issue?

Flail answered 15/8, 2019 at 20:37 Comment(0)
M
3

As previous issue was closed I opened the new one: https://issuetracker.google.com/issues/170328697

And I tried to fix it in this way:

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
            )
        }
    }
}
Makings answered 8/10, 2020 at 9:32 Comment(0)
F
1

Answering my own question, looks like Google fixed the issue https://issuetracker.google.com/issues/37124582

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

Flail answered 29/8, 2019 at 18:27 Comment(3)
1.1.0-alpha was crashing on me too on devices with older version of Android System WebView---on device/emulators like API 21 to 23 (OS5,6). Here is how I was able to get around that https://mcmap.net/q/57666/-android-view-inflateexception-error-inflating-class-android-webkit-webviewFlail
Yes, I saw that and also implemented it this way. Sadly I am using an external sdk where it also crashes and I can't fix it :/ have to wait for them to release a fix versionRebozo
Still present in 1.6.0-rc01Chaffer
A
0

First of all you need to add android.webkit dependency into your project

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

At the time of writing this post the latest stable version of webkit is 1.3.0. It is worth noting that the Dark Theme support has been added with version 1.2.0, before this version it was impossible to add Dark Theme support to Webview.

Next step would be to check whether Webview and Android framework on user’s device supporting theming:

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

Please note that WebViewFeature.FORCE_DARK is only supported starting with Webview version 76. Unfortunately before that version there is no straightforward way to support the dark theming. If you own the contents displayed within the Webview you might want to implement your custom CSS themes and toggle them using @JavascriptInterface from your app.

If WebViewFeature.FORCE_DARK is supported we can choose from three available options:

FORCE_DARK_OFF - Disable dark theme, the content will be rendered in default Light Theme FORCE_DARK_ON - Enable dark theme, the content will be rendered in Dark Theme FORCE_DARK_AUTO - Enable dark theme based on the state of parent view Then we need to apply the setting using WebSettingsCompat

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

You can read about in more detail in the below blogpost

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

Admiralty answered 27/10, 2020 at 18:23 Comment(1)
"WebViewFeature.FORCE_DARK is only supported starting with Webview version 76" - Is there a link where this is mentioned?Absinthe

© 2022 - 2024 — McMap. All rights reserved.