当前位置: 首页 > news >正文

在鸿蒙中实现深色/浅色模式切换:从原理到可运行 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.lryc.cn/news/624125.html

相关文章:

  • 力扣第463场周赛
  • C++---迭代器删除元素避免索引混乱
  • 轻松配置NAT模式让虚拟机上网
  • LeetCode热题100--104. 二叉树的最大深度--简单
  • JavaScript性能优化实战(四):资源加载优化
  • 记SpringBoot3.x + Thymeleaf 项目实现(MVC架构模式)
  • 【Unity3D实例-功能-拔枪】角色拔枪(二)分割上身和下身
  • TDengine IDMP 运维指南(1. 部署规划)
  • 大模型算法岗面试准备经验分享
  • 母猪姿态转换行为识别:计算机视觉与行为识别模型调优指南
  • Java试题-选择题(10)
  • AMBA-AXI and ACE协议详解(四)
  • 计算机毕业设计java的小天鹅酒店月子会所管理小天鹅酒店母婴护理中心管理系统设计小天鹅酒店产后护理会所信息化管理平台
  • 物联网软件开发过程中,数据流图(DFD),用例图,类图,活动图,序列图,状态图,实体关系图(ERD),BPMN(业务流程建模)详解分析
  • 嵌入式练习项目——————抓包获取天气信息
  • Python大模型应用开发-核心技术与项目开发
  • C++编程实战:高效解决算法与数据结构问题
  • Linux817 shell:until,nfs,random
  • React 第七十节 Router中matchRoutes的使用详解及注意事项
  • Next.js跟React关系(Next.js是基于React库的全栈框架)(文件系统路由、服务端渲染SSR、静态生成SSG、增量静态再生ISR、API路由)
  • Vue 与 React 深度对比:设计哲学、技术差异与应用场景
  • 每日Java面试系列(15):进阶篇(String不可变的原因、性能问题、String三剑客、自定义不可变设计、组合优于继承等相关问题)
  • FreeRTOS源码分析八:timer管理(一)
  • Linux学习-多任务(线程)
  • Python 项目里的数据清理工作(数据清洗步骤应用)
  • RK3588开发板Ubuntu系统烧录
  • 「数据获取」《中国教育统计年鉴》(1949-2023)(获取方式看绑定的资源)
  • Python @staticmethod 装饰器与 staticmethod() 函数
  • Spring AI 集成阿里云百炼平台
  • C语言课程开发