在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo

在这里插入图片描述

摘要

现在几乎所有主流应用都支持“深色模式”和“浅色模式”切换,这已经成了用户习惯。鸿蒙(HarmonyOS)同样提供了两种模式(dark / light),并且支持应用根据系统主题切换,或者应用内手动切换。对于开发者来说,如何配置和管理颜色资源,以及如何在代码里实现动态切换,是必须掌握的技能。

本文会从原理到实战,带你实现一个可运行 Demo,并结合实际应用场景,比如电商、阅读类和社交应用,展示不同的实现方式。

引言

早期很多应用为了“省事”,直接写死了颜色值,结果一旦系统切换到深色模式,应用就显得突兀、不协调。鸿蒙的做法比较科学,它提供了 资源限定目录 的机制:在 resources 文件夹里,你可以为不同的颜色模式准备单独的资源文件。

这样一来,应用可以:

  • 跟随系统主题自动切换;
  • 也可以在应用内部提供“主题开关”,让用户手动切换。

接下来我们分两部分讲:

配置资源文件(Light/Dark 模式的颜色文件);
代码层实现动态切换

配置颜色资源

基础做法

首先在 resources 文件夹下新建 Light/Dark 两个目录。方法是右键 -> New Resource Directory -> 勾选 Color Mode,这样会自动生成 lightdark 两个文件夹。

然后在各自的 element 文件夹下创建 color.json 文件,格式如下:

light/element/color.json

{"color": [{"name": "background","value": "#FFFFFF"},{"name": "font_color","value": "#000000"},{"name": "button_background","value": "#0000FF"}]
}

dark/element/color.json

{"color": [{"name": "background","value": "#000000"},{"name": "font_color","value": "#FFFFFF"},{"name": "button_background","value": "#1E90FF"}]
}

这样就完成了“颜色资源”的配置。没配置的情况下,应用会默认使用 base 目录下的颜色值。

动态主题切换实现

跟随系统主题

鸿蒙框架会自动根据系统主题选择 lightdark 资源文件。也就是说,你只要准备好颜色资源,就能实现自动切换。

应用内主动切换

有时候,我们想给用户一个“开关”,让他们在应用内手动选择主题。这时需要调用 UIAppearance 相关接口。

下面是一个最小化 Demo:

// Index.ets
import UIAppearance from '@ohos.arkui.UIAppearance';@Entry
@Component
struct Index {@State isDark: boolean = false;build() {Column({ space: 20 }) {Button(this.isDark ? '切换到浅色模式' : '切换到深色模式').onClick(() => {this.isDark = !this.isDark;UIAppearance.setColorMode(this.isDark ? 'dark' : 'light');})Text('当前主题:' + (this.isDark ? '深色模式' : '浅色模式')).fontColor($r('app.color.font_color')).backgroundColor($r('app.color.background')).fontSize(20).padding(20)}.width('100%').height('100%').backgroundColor($r('app.color.background'))}
}

在上面的代码里:

  • 我们定义了一个 isDark 状态来表示当前主题;
  • 点击按钮后,调用 UIAppearance.setColorMode 主动切换;
  • 文本和背景颜色都使用资源引用 $r('app.color.xxx'),这样能保证跟随主题变化。

场景应用

电商应用:商品展示

在电商类应用中,白天浏览商品时用浅色背景更舒服,晚上则希望用深色模式减少视觉刺激。

Text('¥199.00').fontColor($r('app.color.font_color')).fontSize(24).backgroundColor($r('app.color.background'))

解析:这里字体和背景颜色都是从资源文件里获取的,系统切换主题时自动生效。

阅读应用:夜间模式

阅读类应用通常会提供独立的“夜间模式开关”。即便系统是浅色模式,用户也可能选择在夜间用深色主题。

Toggle({ name: '夜间模式' }, this.isDark).onChange((value: boolean) => {this.isDark = value;UIAppearance.setColorMode(value ? 'dark' : 'light');})

解析:Toggle(开关组件)直接控制主题切换,体验和阅读器常见功能一致。

社交应用:个人设置页面

在社交应用里,主题切换一般放在“设置”页面。

Row() {Text('深色模式').fontSize(18)Switch({ checked: this.isDark }).onChange((val: boolean) => {this.isDark = val;UIAppearance.setColorMode(val ? 'dark' : 'light');})
}

解析:Switch 控件切换主题,同时更新全局 UI。用户在“设置”里调整一次,就能影响所有页面。

常见问题(Q&A)

Q1: 如果没配置 dark 文件夹会怎样?
A: 系统会默认使用 base 下的资源,也就是说不会报错,但主题切换没效果。

Q2: 为什么有时候颜色不跟随主题?
A: 很可能是你在组件里直接写死了颜色值,比如 #FFFFFF,而不是引用 $r('app.color.xxx')

Q3: 应用主动切换和系统主题冲突怎么办?
A: 一般来说,跟随系统是默认行为。如果你在应用里提供了“手动开关”,就要在逻辑上优先考虑用户的选择。

总结

鸿蒙的动态主题切换本质上依赖于 资源限定目录 + UIAppearance API

  • 想跟随系统?准备好 light/dark 资源就行。
  • 想主动切换?调用 UIAppearance.setColorMode()
  • 实际场景里,阅读、电商、社交等应用都能用上主题切换功能,提升用户体验。

写代码时最重要的习惯是:不要写死颜色值,全部走资源引用。这样一来,主题切换就会自然生效,维护起来也轻松。

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

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

相关文章

Redux搭档Next.js的简明使用教程

Redux 是一个用于 JavaScript 应用的状态管理库,主要解决组件间共享状态和复杂状态逻辑的问题。当应用规模较大、组件层级较深或多个组件需要共享/修改同一状态时,Redux 可以提供可预测、可追踪的状态管理方式,避免状态在组件间混乱传递。Red…

SCAI采用公平发射机制成功登陆LetsBonk,60%代币供应量已锁仓

去中心化科学(DeSci)平台SCAI宣布,其代币已于今日以Fair Launch形式在LetsBonk.fun平台成功发射。为保障资金安全与透明,开发团队已将代币总量的60%进行锁仓,进一步提升社区信任与项目合规性。SCAI是一个专注于高质量科…

【Kubernetes系列】Kubernetes中的resources

博客目录1. limits(资源上限)2. requests(资源请求)关键区别其他注意事项示例场景在 Kubernetes (k8s) 中,resources 用于定义容器的资源请求(requests)和限制(limits)&a…

hadoop 前端yarn 8088端口查看任务执行情况

图中资源相关参数含义及简单分析思路&#xff1a; 基础资源抢占参数 Total Resource Preempted: <memory:62112, vCores:6> 含义&#xff1a;应用总共被抢占的资源量&#xff0c; memory:62112 表示累计被收回的内存&#xff08;单位通常是MB &#xff0c;结合Hadoop生态…

基于SpringBoot的个性化教育学习平台的设计与实现(源码+lw+部署文档+讲解等)

课题介绍在教育数字化转型与学习者需求差异化的背景下&#xff0c;传统学习平台 “统一内容、统一进度” 的模式已显局限。当前&#xff0c;平台多提供标准化课程资源&#xff0c;无法根据学习者年龄、基础、目标&#xff08;如升学、技能提升&#xff09;定制学习路径&#xf…

UE5多人MOBA+GAS 48、制作闪现技能

文章目录添加标签添加GA_Blink添加标签 CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Blink_Teleport)CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Blink_Cooldown)UE_DEFINE_GAMEPLAY_TAG_COMMENT(Ability_Blink_Teleport, "Ability.Blink.Teleport"…

Swift 实战:实现一个简化版的 Twitter(LeetCode 355)

文章目录摘要描述示例解决答案设计思路题解代码分析测试示例和结果时间复杂度空间复杂度总结摘要 在社交媒体平台里&#xff0c;推送机制是核心功能之一。比如你关注了某人&#xff0c;就希望在自己的时间线上能看到他们的最新消息&#xff0c;同时自己的消息也要能出现在别人…

在浏览器端使用 xml2js 遇到的报错及解决方法

在浏览器端使用 xml2js 遇到的报错及解决方法 一、引言 在前端开发过程中&#xff0c;我们常常需要处理 XML 数据。xml2js 是一个非常流行的用于将 XML 转换为 JavaScript 对象的库。然而&#xff0c;当我们在浏览器端使用它时&#xff0c;可能会遇到一些问题。本文将介绍在浏览…

eChart饼环pie中间显示总数_2个以上0值不挤掉

<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>环饼图显示总数</title><script src"https://cdn.jsdelivr.net/npm/echarts5.4.3/dist/echarts.min.js"></script><style>#main { widt…

Ansible 核心功能进阶:自动化任务的灵活控制与管理

一、管理 FACTS&#xff1a;获取远程主机的 “身份信息”FACTS 是 Ansible 自动收集的远程主机详细信息&#xff08;类似 “主机身份证”&#xff09;&#xff0c;包括主机名、IP、系统版本、硬件配置等。通过 FACTS 可以动态获取主机信息&#xff0c;让 Playbook 更灵活1. 查看…

gRPC网络模型详解

gRPC协议框架 TCP层&#xff1a;底层通信协议&#xff0c;基于TCP连接。 TLS层&#xff1a;该层是可选的&#xff0c;基于TLS加密通道。 HTTP2层&#xff1a;gRPC承载在HTTP2协议上&#xff0c;利用了HTTP2的双向流、流控、头部压缩、单连接上的多 路复用请求等特性。 gRPC层…

[优选算法专题二滑动窗口——将x减到0的最小操作数]

题目链接 将x减到0的最小操作数 题目描述 题目解析 问题重述 给定一个整数数组 nums 和一个整数 x&#xff0c;每次只能从数组的左端或右端移除一个元素&#xff0c;并将该元素的值从 x 中减去。我们需要找到将 x 恰好减为 0 的最少操作次数&#xff0c;如果不可能则返回 -…

AOP配置类自动注入

本文主要探究AopAutoConfiguration配置类里面的bean怎么被自动装配的。代码如下&#xff1a;package com.example.springdemo.demos.a05;import com.example.springdemo.demos.a04.Bean1; import com.example.springdemo.demos.a04.Bean2; import com.example.springdemo.demos…

云计算-K8s 实战:Pod、安全上下文、HPA 、CRD、网络策略、亲和性等功能配置实操指南

简介 此次围绕Kubernetes 日常管理中的核心场景,提供了从基础到进阶的实操配置指南。内容涵盖 9 大关键知识点:从使用 nginx 镜像创建 QoS 类为 Guaranteed 的 Pod,到为 Pod 配置安全上下文以指定运行用户和组;从自定义 Student 资源类型(CRD),到配置 Sidecar 实现跨命…

嵌入式LINUX——————TCP并发服务器

一、服务器1.服务器分类单循环服务器&#xff1a;只能处理一个客户端任务的服务器 并发服务器&#xff1a;可同时处理多个客户端任务的服务器二、TCP并发服务器的构建1.如何构建&#xff1f; &#xff08;1&#xff09;多进程&#xff08;每一次创建都非常耗时耗空间&#…

论文润色不能降低文章的重复率

最近大家问到多的&#xff0c;你们润色好了重复率会不会就降低了。这事儿啊&#xff0c;得从好几个方面去剖析&#xff0c;今天咱们就一块儿来探个究竟。咱们先得清楚&#xff0c;重复率检测工具一般会把内容标记成两类&#xff1a;一是那些和其他文献在文字表达上高度相似的部…

Python爬虫实战:构建alltheplaces平台地理信息数据采集系统

1. 引言 1.1 研究背景与意义 在大数据与智慧城市建设的推动下,地理位置信息(如餐馆、景点、公共设施等 POI 数据)已成为商业分析、城市规划、公共服务优化的核心基础数据。alltheplaces 作为全球领先的开放场所数据平台,整合了来自多个数据源的标准化信息,涵盖场所名称、…

HTML第三次作业

抽奖项目代码<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>简易抽奖转盘</title><sty…

PyTorch 面试题及详细答案120题(01-05)-- 基础概念与安装

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

云手机选哪个比较好用?

云手机作为基于云计算技术运行的一款虚拟手机&#xff0c;能够帮助企业与个人用户进行账号多开和远程访问等多种功能&#xff0c;是手游玩家的首要选择&#xff0c;能够多开账号挂机不卡顿&#xff0c;但是哪一款云手机更加流畅好用呢&#xff1f;对于热衷于手游的玩家来说&…