Android WebView 深色模式适配方案总结

在 Android WebView 中适配深色模式(Dark Mode)是一个常见的需求,尤其是当加载的网页没有原生支持 prefers-color-scheme 时。本文将介绍 3 种主流方案,并分析它们的优缺点,帮助开发者选择最佳实现方式。


方案 1:JS 动态注入 CSS(适合任意网页)

核心思路

通过 JavaScript 动态插入 CSS,强制修改网页的背景、文字颜色等样式。

代码实现(Kotlin)

fun applyDarkMode(webView: WebView, isDarkMode: Boolean) {val css = if (isDarkMode) {"""html, body, body * {background-color: #1a1a1a !important;color: #e0e0e0 !important;}/* 隐藏某些元素 */#ad-container { display: none !important; }"""} else {"""html, body, body * {background-color: #ffffff !important;color: #000000 !important;}"""}val js = """var style = document.createElement('style');style.innerHTML = `${css.replace("\n", "")}`;document.head.appendChild(style);""".trimIndent()webView.evaluateJavascript(js, null)
}

调用时机

webView.webViewClient = object : WebViewClient() {override fun onPageFinished(view: WebView?, url: String?) {applyDarkMode(webView, isDarkMode)}
}

优缺点

优点

  • 适用于任何网页(包括第三方网页)。
  • 可精细控制特定元素的样式(如隐藏广告)。

缺点

  • 可能受 CSP(内容安全策略)限制,导致注入失败。
  • 部分网页可能因 CSS 优先级问题无法覆盖默认样式。

方案 2:强制 WebView 深色渲染(API 29+)

核心思路

Android 10 (API 29) 引入了 WebSettingsCompat.FORCE_DARK,可让 WebView 自动适配深色模式。

代码实现

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {WebSettingsCompat.setForceDark(webView.settings,if (isDarkMode) WebSettingsCompat.FORCE_DARK_ON else WebSettingsCompat.FORCE_DARK_OFF)
}

适配网页

网页需支持 prefers-color-scheme

/* 深色模式适配 */
@media (prefers-color-scheme: dark) {body {background: #121212;color: #f0f0f0;}
}

优缺点

优点

  • 系统级支持,兼容性较好(适用于支持 prefers-color-scheme 的网页)。
  • 无需手动注入 CSS,减少代码维护成本。

缺点

  • 仅适用于 API 29+。
  • 如果网页未适配 prefers-color-scheme,可能渲染异常。

方案 3:拦截并修改网页内容(高级方案)

核心思路

通过 WebViewClient.shouldInterceptRequest 拦截 HTML/CSS,动态替换样式。

代码示例

webView.webViewClient = object : WebViewClient() {override fun shouldInterceptRequest(view: WebView?,request: WebResourceRequest?): WebResourceResponse? {if (request?.url?.toString()?.endsWith(".css") == true) {// 修改 CSS 内容val darkCss = """body { background: #1a1a1a !important; }""".trimIndent()return WebResourceResponse("text/css","UTF-8",ByteArrayInputStream(darkCss.toByteArray()))}return super.shouldInterceptRequest(view, request)}
}

优缺点

优点

  • 可深度定制网页样式,甚至替换整个 CSS 文件。
  • 不受 CSP 限制,适用于严格安全策略的网页。

缺点

  • 实现复杂,需处理各种资源加载情况。
  • 可能影响网页功能(如动态加载的样式)。

最佳实践推荐

方案适用场景兼容性实现难度
JS 注入 CSS任意网页,需动态调整样式所有版本⭐⭐
WebView 强制深色网页已支持 prefers-color-schemeAPI 29+
拦截修改网页需要深度定制样式所有版本⭐⭐⭐

推荐方案

  1. 优先检查网页是否支持 prefers-color-scheme,如果支持,使用 方案 2FORCE_DARK)。
  2. 如果网页不受控(如第三方页面),使用 方案 1(JS 注入 CSS)。
  3. 如果需要更高级控制(如企业定制页面),可尝试 方案 3(拦截修改)。

总结

在 Android WebView 中实现深色模式,主要有 动态注入 CSS系统强制深色渲染拦截修改网页 三种方式。选择方案时需考虑:

  • 网页是否可控(能否修改 CSS?)
  • Android 版本兼容性(是否需要支持旧版?)
  • 是否需要精细控制(如隐藏广告、修改字体等)

如果你的网页可控,建议直接使用 prefers-color-scheme + FORCE_DARK;如果是第三方网页,JS 注入 CSS 是最稳妥的方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/84959.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/84959.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/84959.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目练习:使用mybatis的foreach标签,实现union all的拼接语句

文章目录 一、需求说明二、需求分析三、代码实现四、报表效果 一、需求说明 在sql查询数据后,对数据分组统计。并最后进行总计。 二、需求分析 最终,我想用sql来实现这个统计和查询的功能。 那么,怎么又查询,又统计了&#xf…

7.7 Extracting and saving responses

Chapter 7-Fine-tuning to follow instructions 7.7 Extracting and saving responses 在本节中,我们保存测试集响应以便在下一节中评分,除此之外保存模型的副本以供将来使用。 ​ 首先,让我们简单看看finetuned模型生成的响应 torch.manu…

计算机网络第3章(上):数据链路层全解析——组帧、差错控制与信道效率

目录 一、数据链路层的功能二、组帧2.1 字符计数法(Character Count)2.2 字符填充法(Character Stuffing)2.3 零比特填充法2.4 违规编码法 三、差错控制3.1 检错编码(奇偶校验码)3.2 循环冗余校验&#xff…

铸铁试验平台的重要性及应用前景

铸铁作为一种重要的金属材料,在工业生产中扮演着举足轻重的角色。为了确保铸铁制品的质量和性能,铸铁材料的试验是必不可少的环节。而铸铁试验平台则是进行铸铁试验的关键设备之一,它为铸铁材料的研究和开发提供了重要的技术支持。本文将探讨…

std::shared_ptr引起内存泄漏的例子

目录 一、循环引用(最常见场景) 示例代码 内存泄漏原因 二、共享指针管理的对象包含自身的 shared_ptr 示例代码 内存泄漏(或双重释放)原因 三、解决方案 1. 循环引用:使用 std::weak_ptr 2. 对象获取自身的 …

AI 知识数据库搭建方案:从需求分析到落地实施

AI 知识数据库的搭建需结合业务场景、数据特性与技术架构,形成系统化解决方案。以下是一套完整的搭建框架,涵盖规划、设计、实施及优化全流程: 一、前期规划:需求分析与目标定义 1. 明确业务场景与知识需求 场景导向&#xff1a…

Tensorflow 基础知识:变量、常量、占位符、Session 详解

在深度学习领域,TensorFlow 是一个广泛使用的开源机器学习框架。想要熟练使用 TensorFlow 进行模型开发,掌握变量、常量、占位符和 Session 这些基础知识是必不可少的。接下来,我们就深入了解一下它们的概念、用处,并通过代码示例进行演示。 一、常量(Constant) 常量,顾…

linux 常见问题之如何清除大文件的内容

linux 常见问题之如何清除大文件的内容 在 Linux 系统中,我们有时会遇到文件随着时间增长变得巨大,最常见的就是服务器的日志文件,随着时间的推移占用大量的磁盘空间,下面介绍如何清楚大文件的内容,当然避免文件内容过…

薛定谔的猫思想实验如何推演到量子计算

前言 这是我的选修课作业,但是我并不喜欢小论文方式的写法,死板又老套。先在这打一份底稿。 薛定谔的猫 可能一说到量子这个关键词,大家第一时间都会想到的是“薛定谔的猫”。 实验介绍 薛定谔的猫是一个著名的思想实验,由奥…

嵌入式开发中fmacro-prefix-map选项解析

在嵌入式开发中,-fmacro-prefix-map 是 GCC 和 Clang 等编译器提供的一个路径映射选项,主要用于在预处理阶段重写宏定义中出现的绝对路径。它的核心目的是解决以下问题: 核心作用 构建可重现性 消除编译输出(如 .o、.d 文件&…

Javaweb学习——day3(Servlet 中处理表单数据)

文章目录 一、概念学习1. GET vs POST 请求方式的区别2. HttpServletRequest 获取表单数据 二、代码讲解与练习第 1 步:在 webapp 下创建 login.html第 2 步:在 com.example 包下创建 LoginServlet第 3 步:修改 web.xml 注册 LoginServlet第 …

在 iOS 开发中单独解析域名为 IP

1 为什么要自己解析? 典型场景说明劫持/污染检测比较 系统解析 与 自建 DNS 的差异QoS / CDN 选路对每个候选 IP 做 RT/丢包测速系统 API(NSURLSession / Network.framework)在「真正建立连接之前」不会把解析结果暴露出来,因此需要主动解析一步。 2 API 选型概览 API是否过…

YOLOv1 技术详解:正负样本划分与置信度设计

🔍 YOLOv1 技术详解:正负样本划分与置信度设计 一、前言 YOLOv1 是目标检测领域中具有划时代意义的算法之一,它将检测任务统一为一个回归问题,实现了“You Only Look Once”的端到端实时检测。其中,正负样本的划分机…

为 Nginx 配置 HTTPS(以 n8n 为例)完整教程【CentOS 7】

在部署如 n8n 这类自动化平台时,为了保障数据传输安全,我们通常会使用 HTTPS 访问。本文将以 n8n.example.com 为例,介绍如何在 CentOS 7 系统中通过 Nginx 为本地运行在端口 5678 的 n8n 服务配置免费 SSL 证书(Let’s Encrypt&a…

Elasticsearch从安装到实战、kibana安装以及自定义IK分词器/集成整合SpringBoot详细的教程ES(四)查询、排序、分页、高亮

基础代码 package com.test.xulk;import com.alibaba.fastjson.JSON; import com.test.xulk.es.esdoc.HotelDoc; import com.test.xulk.es.service.IHotelService; import org.apache.http.HttpHost; import org.elasticsearch.action.search.SearchRequest; import org.elast…

一个数组样式上要分成两个

如图所示&#xff0c;要有一个区分来显示&#xff0c;如果一开始就是这样还可以有很多种处理方式&#xff0c;但是这个后期一直在调整所以不好重做因为开发已经完成&#xff0c;加上很多地方联动改的地方太多&#xff0c;所以采用了一个比较笨的方法 <ul class"classif…

NLP进化史:从规则模板到思维链推理,七次范式革命全解析

“语言不是神的创造物&#xff0c;而是平凡人类的产物。”——诺姆乔姆斯基 自然语言处理&#xff08;NLP&#xff09;的发展史&#xff0c;就是人类试图教会机器理解语言本质的探索史。本文将带您穿越70年技术长河&#xff0c;揭示NLP领域关键的范式转换里程碑。 一、规则驱动…

Yarn与NPM缓存存储目录迁移

Yarn与NPM缓存存储目录迁移 背景与需求 解释Yarn和NPM缓存机制的作用及默认存储路径迁移缓存目录的常见原因&#xff08;如磁盘空间不足、系统盘性能优化、多项目协作需求&#xff09; Yarn缓存目录迁移方法 查看当前Yarn缓存目录的命令&#xff1a;yarn cache dir修改Yarn…

Python爬虫-批量爬取快手视频并将视频下载保存到本地

前言 本文是该专栏的第80篇,后面会持续分享python爬虫干货知识,记得关注。 本文笔者以快手为例子,基于Python爬虫来实现批量采集视频,并将视频下载以及保存到本地。 而具体的“视频采集以及视频下载,保存”思路逻辑,笔者将在正文中结合“完整代码”来详细介绍每个步骤。…

org.springframework.cloud.openfeign 组件解释

我们来详细解释一下 org.springframework.cloud.openfeign 这个组件。 一句话概括&#xff1a;它是一个声明式的、模板化的HTTP客户端&#xff0c;旨在让微服务之间的REST API调用变得像调用本地方法一样简单。 为了让你彻底理解&#xff0c;我会从以下几个方面来解释&#x…