在 WebView 中调暗 Web 内容

在 Android 10 及更高版本中,应用可支持 深色主题,会自动更改 根据系统主题调整浅色和深色应用主题。为了匹配 当前应用主题,WebView 中的 Web 内容 也可以使用浅色、深色或默认样式

WebView 的行为 prefers-color-schemecolor-scheme 网络标准如果您创作的是自己需要的网络内容 您的应用要显示在 WebView 中时,您应为您的应用定义一个深色主题背景 网站和 实现 prefers-color-scheme,以便 WebView 与 Web 内容的 应用主题

下表介绍了 WebView 如何在应用中呈现 Web 内容。 具体取决于 Web 内容的样式和应用条件:

应用条件 使用 prefers-color-scheme 的 Web 内容 不使用 prefers-color-scheme 的 Web 内容
应用使用的是浅色主题 isLightTheme 设置为 true 或未设置。 WebView 使用浅色主题来渲染内容, WebView 使用 内容作者。
应用正在使用 强制深色模式 更改为 通过算法应用深色主题 WebView 使用深色主题渲染内容, 如果内容作者允许,WebView 会使用 使用算法生成的深色主题。
应用使用的是深色主题,并且 isLightTheme 设为 false,且应用不允许使用算法 对 WebView 进行调暗 WebView 使用深色主题渲染内容, WebView 使用 内容作者。
应用使用的是深色主题,并且 isLightTheme 设为 false,且应用允许 WebView 的算法加深功能 WebView 使用深色主题渲染内容, 如果内容作者允许,WebView 会使用 使用算法生成的深色主题。

内容作者样式

应用的 isLightTheme 属性 指示应用的主题是浅色还是深色。WebView 始终设置 prefers-color-scheme,数据来源:isLightTheme。如果 isLightThemetrue 或未指定,则 prefers-color-schemelight;否则 dark

这意味着,如果 Web 内容使用 prefers-color-scheme,并且内容 内容创作者定义的浅色或深色主题 始终自动应用于 Web 内容,以匹配应用的主题。

算法加深

为了涵盖网页内容不使用 prefers-color-scheme、 您的应用可以允许 WebView 在必要时通过算法应用深色 主题应用到所呈现的 Web 内容中。

如果您的应用使用的是应用级 根据算法从 Force Dark 对应用应用深色主题,请参阅下一部分,了解如何 允许通过 Force Dark 使用算法调暗 Web 内容

如果您的应用未使用 Force Dark,应用会如何指定何时允许使用 Force Dark WebView 中的算法加暗取决于应用的 目标 API 级别。 如需了解以 Android 13 或更高版本为目标平台的应用以 Android 12 或更低版本为目标平台的应用

使用 Force Dark 使用算法调暗网页内容

如果您的应用使用的是应用级 Force Dark,WebView 适用 如果满足以下条件,则系统对 Web 内容进行算法加暗:

  • WebView 及其父元素允许使用 Force Dark。
  • 当前 activity 主题标记为浅色, isLightTheme已设为 true
  • 网络内容作者没有明确停用调暗功能。
  • 对于以 Android 13(API 级别 33)或更高版本为目标平台的应用,网页内容 未使用 prefers-color-scheme
  • 对于以 Android 12(API 级别 32)或更低版本为目标平台的应用:应用已设置 WebView 的 forceDarkMode 设置 更改为 FORCE_DARK_AUTO 他们将 Force Dark 策略设为 DARK_STRATEGY_USER_AGENT_DARKENING_ONLY

WebView 及其所有父项可以使用 View.setForceDarkAllowed()。 默认值取自setForceDarkAllowed() Android 主题,还必须设置为 true

Force Dark 模式主要是为了向后兼容 未提供自己的深色主题。 如果您的应用使用 Force Dark,我们建议您 添加对深色主题的支持

允许通过算法加深(以 Android 13 或更高版本为目标平台的应用)

对于未使用应用级 Force Dark 且以 Android 13(API 级别)为目标平台的应用 33) 或更高版本,请使用 AndroidX setAlgorithmicDarkeningAllowed() 方法并传入 true,以指定 WebView 应允许算法 变暗。此方法向后兼容旧版 Android 版本。

如果满足以下条件,WebView 就会应用算法加深功能:

  • 网页内容未使用 prefers-color-scheme
  • 网络内容作者没有明确停用调暗功能。

允许通过算法加深(以 Android 12 或更低版本为目标平台的应用)

对于未使用应用级 Force Dark 且以 Android 12(API 级别)为目标平台的应用 32) 或更低版本,请使用 FORCE_DARK_ON 以允许算法加深。

FORCE_DARK_ON 与以下功能搭配使用 FORCE_DARK_OFF 如果您的应用自行提供在浅色主题和深色主题之间切换的方法, 例如界面中的可切换元素或基于时间的自动选择。

要检查功能是否受支持,请添加以下代码行 在任何位置配置 WebView 对象,例如在 Activity.onCreate 中:

Kotlin

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

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    WebSettingsCompat.setForceDark(...);
}

如果您的应用依赖于检测系统偏好设置的变化,则应该 明确监听主题更改,并使用 FORCE_DARK_ONFORCE_DARK_OFF 状态。

以下代码段展示了如何更改主题格式:

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) {
        Configuration.UI_MODE_NIGHT_YES -> {
            WebSettingsCompat.setForceDark(myWebView.settings, FORCE_DARK_ON)
        }
        Configuration.UI_MODE_NIGHT_NO, Configuration.UI_MODE_NIGHT_UNDEFINED -> {
            WebSettingsCompat.setForceDark(myWebView.settings, FORCE_DARK_OFF)
        }
        else -> {
            //
        }
    }
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
    switch (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) {
        case Configuration.UI_MODE_NIGHT_YES:
            WebSettingsCompat.setForceDark(myWebView.getSettings(), FORCE_DARK_ON);
            break;
        case Configuration.UI_MODE_NIGHT_NO:
        case Configuration.UI_MODE_NIGHT_UNDEFINED:
            WebSettingsCompat.setForceDark(myWebView.getSettings(), FORCE_DARK_OFF);
            break;
    }
}

自定义深色主题处理

您还可以使用 ForceDarkStrategy API 以控制对指定 WebView 应用调暗的方式。此 API 是 仅在强制深色设置为 FORCE_DARK_ONFORCE_DARK_AUTO 时才适用。

借助该 API,您的应用可以使用网页主题加深功能或用户代理 变暗:

  • 网络主题变暗:网站开发者可能会 @media (prefers-color-scheme: dark),用于控制 深色模式WebView 根据这些设置呈现内容。如需详细了解 调暗网页主题,请参阅 规范
  • 用户代理调暗:WebView 会自动反转网页颜色 页面。如果您使用用户代理加深颜色, “@media (prefers-color-scheme: dark)”查询的计算结果为 false

如需在两种策略之间进行选择,请使用以下 API:

Kotlin

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    WebSettingsCompat.setForceDarkStrategy(...)
}

Java

if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
    WebSettingsCompat.setForceDarkStrategy(...);
}

支持的策略选项包括:

  • <ph type="x-smartling-placeholder"></ph> DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING: 这是默认选项。虽然大多数浏览器将 <meta name="color-scheme" content="dark light"> 标记作为可选标记,Android WebView 的默认模式要求元标记遵循网页的 prefers-color-scheme 个媒体查询。您可以将 WebView 与 <ph type="x-smartling-placeholder"></ph> DARK_STRATEGY_WEB_THEME_DARKENING_ONLY 模式,在这种情况下,WebView 始终会应用媒体查询,即使代码 。

    不过,我们建议网络开发者 <meta name="color-scheme" content="dark light"> 代码添加到他们的网站, 使用 默认配置。

  • <ph type="x-smartling-placeholder"></ph> DARK_STRATEGY_USER_AGENT_DARKENING_ONLY: 称为“用户代理加深”WebView 会忽略所有让网页变暗且 自动调暗背景。

如果您的应用显示您使用 prefers-color-scheme 个媒体查询,我们建议使用 DARK_STRATEGY_WEB_THEME_DARKENING_ONLY 以确保 WebView 使用自定义主题。

有关应用深色主题的示例,请参阅 GitHub 上的 WebView 演示