更新 2022:AndroidX Webkit 1.5.0修复了webview处理暗黑模式的许多怪异问题。
为使其正常工作,您需要:
- 向项目添加最新版本的webkit(至少为1.5.0):
implementation 'androidx.webkit:webkit:1.5.0'
- 将应用程序的目标版本设置为33或更高版本
- 确保设备上安装了Android系统Webview v100或更高版本
通过此设置,webview将根据应用程序主题进行适当调整,无需进一步调整任何设置。
prefers-color-scheme
CSS查询值将自动根据当前活动/片段运行的主题类型(浅色/深色)调整为浅色或深色。(基于主题或其父主题的isLightTheme
属性)
如果您的应用程序targetSdkVersion
设置为33或更高版本,则调整暗黑模式的pre-API 33方法(例如WebViewSettingsCompat.setForceDark
和WebViewSettingsCompat.setForceDarkStrategy
等)将不起作用,并且可以从代码中删除。
注意:此新方法要求您的应用程序目标为API 33或更高版本,但向后兼容至少到API 29(支持暗黑模式的第一个Android版本)
注意2:在大多数情况下,用户代理变暗(不支持自动暗黑模式的网页的自动暗黑模式)现已默认禁用,但可以使用以下方法启用:
if(WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) {
WebSettingsCompat.setAlgorithmicDarkeningAllowed(myWebView.getSettings(), true);
}
这种方法的完整行为描述可以在这里找到。
传统方法(面向API 32或以下的应用程序)
Android Webview在面向API 32及以下的应用程序中处理日/夜模式与其他视图有所不同。
将主题设置为暗色将更改WebView组件(滚动条、缩放按钮等)为深色模式版本,但不会更改其加载的内容。
要更改内容,您需要使用webview设置的setForceDark方法使其也更改其内容。此方法的兼容版本可在AndroidX Webkit包中找到。
将以下依赖项添加到gradle构建中:
implementation 'androidx.webkit:webkit:1.3.0'
(1.3.0是此软件包所需的最低版本。但更高的版本也应该可以使用。)
并将以下代码添加到您的Webview初始化中:
if(WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(myWebView.getSettings(), WebSettingsCompat.FORCE_DARK_ON);
}
检查 isFeatureSupported
的存在是为了确保用户设备上安装的 Android System WebView 版本支持暗模式(因为这可以通过 Google Play 独立更新或降级,与 Android 版本无关)。
注意:要在运行设备上安装 Android System WebView v76 或更高版本才能使用 setForceDark
功能。
WebView 内容的强制暗模式功能有两种所谓的策略:
要设置 WebView 应该使用哪种策略来应用强制暗模式,您可以使用以下代码:
if(WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
WebSettingsCompat.setForceDarkStrategy(myWebView.getSettings(), WebSettingsCompat.DARK_STRATEGY_WEB_THEME_DARKENING_ONLY)
}
注意: 策略选择需要在运行设备上安装 Android System WebView v83 或更高版本。支持 setForceDark
但不支持策略选择的 WebView 版本(从 v76 到 v81)将使用用户代理变暗。
支持的策略选项包括:
- DARK_STRATEGY_USER_AGENT_DARKENING_ONLY:仅使用用户代理变暗并忽略内容中的任何主题(默认)
- DARK_STRATEGY_WEB_THEME_DARKENING_ONLY:仅使用内容自身的深色主题来设置页面为暗模式。如果内容没有深色主题,则 WebView 不会应用任何变暗并显示它“原样”。
- DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING:使用内容自身的深色主题来设置页面为暗模式。如果内容没有深色主题,则使用用户代理变暗。
暗网页的 Javascript 检查是如何工作的?
JavaScript 调用 window.matchMedia('(prefers-color-scheme: dark)')
将在用户代理变暗和网页主题变暗策略中匹配。
我已将我的 webview 设置为 FORCE_DARK_AUTO,我的应用正在运行 DayNight 主题,但不知何故我的 webview 不会根据我的应用主题自动应用暗模式。为什么会发生这种情况?
这是因为 WebView 的 FORCE_DARK_AUTO
设置值不基于主题工作(如 文档 中所述)。它检查 Android 10 强制暗模式 功能(应用的“快速修复”暗模式功能。名称类似,但与 WebView 强制暗模式没有直接关系)。
如果您没有使用强制暗模式而是使用应用程序主题来处理暗模式(建议使用),则必须实现自己的检查以确定何时应用 WebView 的强制暗模式功能。以下是使用 DayNight 主题的示例:
int nightModeFlags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
if (nightModeFlags == Configuration.UI_MODE_NIGHT_YES) {
}
prefers-color-scheme: dark
设置起作用? - Inês Borges<head>
标签中添加了<meta name="color-scheme" content="light dark">
。 - Inês Borges