はじめに
AndroidはChromeで強制ダークモードが使えるため、
WebViewも可能だろうと思い調べてみたところ、
設定が思いのほか複雑だったので、まとめてみました
設定方法
SDK Versionとダークモードの適用方法(ダークモード対応サイトのみ、強制ダークモード)によって、設定を分類しています
SDK Version 33
- Theme_isLightTheme
-
setAlgorithmicDarkeningAllowed()
-
androidx.webkit:webkit:1.5.0
のAPI - 初期値は
false
-
ダークモード対応サイトのみダークモードにする
WebViewもしくは、より上位のViewにTheme_isLightThemeが定義されたThemeを設定する
<WebView
android:id="@+id/web_view"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:theme="@style/Theme.MaterialComponents.DayNight"/>
全てのサイトをダークモードにする
Theme_isLightThemeとsetAlgorithmicDarkeningAllowed() をtrue
に設定する
true
に設定しても、ダークモード対応サイトはそのサイトで定義されたカラーで表示される
if(WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) {
WebSettingsCompat.setAlgorithmicDarkeningAllowed(binding.webView.settings, true)
}
SDK Version 29〜32
-
setForceDark()
-
FORCE_DARK_AUTO (初期値)
- Referenceに以下の記述があるため、ダークモード対応アプリでは使えない
If your app uses a dark theme, WebView will not be inverted. Similarly, if your app's theme inherits from a DayNight theme, WebView will not be inverted. In either of these cases, you should control the mode manually with FORCE_DARK_ON or FORCE_DARK_OFF.
- Referenceに以下の記述があるため、ダークモード対応アプリでは使えない
- FORCE_DARK_ON
- FORCE_DARK_OFF
-
FORCE_DARK_AUTO (初期値)
-
setForceDarkStrategy() ※ setForceDark()を呼び出すと値が変わるため注意
- DARK_STRATEGY_WEB_THEME_DARKENING_ONLY (初期値)
- DARK_STRATEGY_USER_AGENT_DARKENING_ONLY
-
DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING
- Referenceにはダークモード対応サイトはそのサイトで定義された配色で表示されるような旨が記載されていますが、動作確認したところ強制ダークモードの配色になってしまいました
(原因は現状不明です。。)
- Referenceにはダークモード対応サイトはそのサイトで定義された配色で表示されるような旨が記載されていますが、動作確認したところ強制ダークモードの配色になってしまいました
ダークモード対応サイトのみダークモードにする
ダークON/OFF設定とsetForceDark()の値を同期させて、setForceDarkStrategy()をDARK_STRATEGY_WEB_THEME_DARKENING_ONLYに設定する
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK) && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
Configuration.UI_MODE_NIGHT_YES -> {
WebSettingsCompat.setForceDark(binding.webView.settings, WebSettingsCompat.FORCE_DARK_ON)
}
Configuration.UI_MODE_NIGHT_NO, Configuration.UI_MODE_NIGHT_UNDEFINED -> {
WebSettingsCompat.setForceDark(binding.webView.settings, WebSettingsCompat.FORCE_DARK_OFF)
}
}
WebSettingsCompat.setForceDarkStrategy(binding.webView.settings, WebSettingsCompat.DARK_STRATEGY_WEB_THEME_DARKENING_ONLY)
}
全てのサイトをダークモードにする
ほぼ同じで、違いはsetForceDarkStrategy()の設定値をDARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENINGにする
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK) && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
Configuration.UI_MODE_NIGHT_YES -> {
WebSettingsCompat.setForceDark(binding.webView.settings, WebSettingsCompat.FORCE_DARK_ON)
}
Configuration.UI_MODE_NIGHT_NO, Configuration.UI_MODE_NIGHT_UNDEFINED -> {
WebSettingsCompat.setForceDark(binding.webView.settings, WebSettingsCompat.FORCE_DARK_OFF)
}
}
WebSettingsCompat.setForceDarkStrategy(binding.webView.settings, WebSettingsCompat.DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING)
}
SDK Version 〜28
ダークモードに対応していないため、ライトテーマでの表示となる
おまけ : Chromeの強制ダークモード設定方法
chrome://flags
-> Auto Dark Mode for Web Contents : Enabled
参考にさせていただいたリンク