display name
display name

Reputation: 899

WebView resetting UiMode and breaking dark theme

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?

Upvotes: 9

Views: 4456

Answers (3)

John Smith
John Smith

Reputation: 874

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

Upvotes: 0

kr1s
kr1s

Reputation: 63

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

Upvotes: 4

display name
display name

Reputation: 899

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

Upvotes: 1

Related Questions