我有一个使用 webview 的 Android 应用程序,最近我试图弄清楚如何使用新的 @media (prefers-color-scheme: dark)
CSS 语法来添加深色主题。我在我的页面上写了正确的 CSS,如果我在 Chrome 中打开它并打开 Chrome 的暗模式,它就可以工作。我也有我的 AppTheme
继承 Theme.AppCompat.DayNight
,当我为设备上的整个操作系统打开暗模式时,我的应用程序显示暗加载对话框等。甚至 <input>
元素的自动完成选项也会变暗。但是,我的 webview 加载的网页仍然没有变暗。根据 这个页面,webviews 应该支持这个特性,但我就是不能让它工作。我在这里想念什么?
我还刚刚发现在 API 29 中有这个 WebSettings.setForceDark()
方法;会不会是我要找的东西?我希望找到一个适用于较低 API 级别的解决方案。
顺便说一句,我目前的解决方法是注入这样的 JavaScript 接口:
webView.addJavascriptInterface(new JSInterface(), "jsInterface");
...
public class JSInterface {
@JavascriptInterface
public boolean isNightMode() {
int nightModeFlags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
return nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
}
}
然后在我的网页中,调用 jsInterface.isNightMode()
方法并根据结果动态加载不同的 CSS 文件。它确实可以根据需要对全局暗模式设置做出响应,但我仍然想知道是否可以使 prefers-color-scheme
工作。
原文由 Mu-Tsun Tsai 发布,翻译遵循 CC BY-SA 4.0 许可协议
Android Webview 处理日/夜模式与其他视图略有不同。将您的主题设置为深色会将 WebView 组件(滚动条、缩放按钮等)更改为深色模式版本,但不会更改它加载的内容。
要更改内容,您需要使用 webview 设置的 setForceDark 方法使其也更改其内容。此方法的兼容版本可以在 AndroidX webkit 包中找到。
将以下依赖项添加到您的 gradle 构建中:
(1.3.0 是此软件包的最低要求版本。但更高版本也应该可以工作。)
并将以下代码行添加到您的 webview 初始化中:
isFeatureSupported
检查以确保用户在其设备上安装的 Android 系统 WebView 版本支持暗模式(因为这可以通过 Google Play 独立于 Android 版本进行更新或降级)。注意:
setForceDark
功能需要在运行的设备上安装 Android System WebView v76 或更高版本。webview 内容的 force dark 功能有两个所谓的策略:
用户代理变暗: webview 将通过自动反转或变暗其内容的颜色将其内容设置为暗模式。
基于主题的变暗: webview 将根据内容的主题(包括
@media (prefers-color-scheme: dark)
查询)更改为暗模式。要设置 webview 应该使用哪种策略来应用强制黑暗,您可以使用以下代码:
注意: 策略选择需要在运行设备上安装 Android System WebView v83 或更高版本。支持
setForceDark
但不支持策略选择(v76 到 v81)的 WebView 版本将使用用户代理变暗支持的策略选项有:
JavaScript 调用
window.matchMedia('(prefers-color-scheme: dark)')
将匹配用户代理变暗和 Web 主题变暗策略。这是因为
FORCE_DARK_AUTO
webview 的设置值不适用于主题(如 文档中所述)。它检查 Android 10 强制黑暗 功能(应用程序的“快速修复”黑暗模式功能。它的名称相似,但与 WebView 强制黑暗没有直接关系)。如果您没有使用强制黑暗,而是使用应用程序主题来处理黑暗模式(如推荐的那样),您必须自己检查何时应用 webview 的强制黑暗功能。使用 DayNight 主题的示例: