当前位置: 首页 > 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.xdnf.cn/news/1317079.html

相关文章:

  • E2B是一个开源基础设施,允许您在云中安全隔离的沙盒中运行AI生成的代码和e2b.dev网站
  • Diamond基础2:开发流程之LedDemo
  • c_str()函数的详细解析
  • 简单的 VSCode 设置
  • (nice!!!)(LeetCode 每日一题) 837. 新 21 点 (动态规划、数学)
  • bash shell 入门
  • 云智智慧停充一体云-allnew全新体验-路内停车源码+路外停车源码+充电桩源码解决方案
  • Rust:DLL 输出对象的生命周期管理
  • API生命周期10阶段
  • 原子操作及基于原子操作的shared_ptr实现
  • Baumer高防护相机如何通过YoloV8深度学习模型实现工作设备状态的检测识别(C#代码UI界面版)
  • 【C++】Windows 下 TCP接口超详介绍,如何实现一个TCP服务端和客户端
  • Windows 10共享打印机操作指南
  • 业务员手机报价软件免费领取——仙盟创梦IDE
  • 精美UI的单页网盘资源分享搜索页面 短剧搜索 自适应页面
  • 飞算JavaAI赋能高吞吐服务器模拟:从0到百万级QPS的“流量洪峰”征服之旅
  • IC验证 AHB-RAM 项目(一)——项目理解
  • AOP配置类自动注入
  • Git安装使用
  • Java增强for循环(小白友好版)
  • 整体设计 之“凝聚式中心点”原型 --整除:智能合约和DBMS的深层联合 之1
  • 【R语言】R语言矩阵运算:矩阵乘除法与逐元素乘除法计算对比
  • 7 索引的监控
  • 一文读懂[特殊字符] LlamaFactory 中 Loss 曲线图
  • JavaScript字符串详解
  • 图解希尔排序C语言实现
  • 力扣 hot100 Day76
  • Java 基础 -- Java 基础知识
  • C语言---第一个C语言程序
  • FreeRTOS源码分析八:timer管理(一)