HarmonyOS 深色模式优雅适配:资源 + 代码双管齐下
·
HarmonyOS 深色模式优雅适配:资源 + 代码双管齐下
前言
深色模式不是简单地"把背景涂黑",它涉及颜色资源的体系化管理、系统色彩模式的监听、以及应用内手动切换的覆盖逻辑。本文基于论坛问题「HarmonyOS 应用如何优雅地做深色模式适配」,给出一套零硬编码、可维护的适配方案,让浅/深两套配色自动切换,同时支持用户手动覆盖。
问题描述
- 直接写死
0xFFFFFF/0x000000等颜色,切换深色模式后界面"一半亮一半暗"; - 只在某个页面手动判断了深浅,其它页面没适配,风格割裂;
- 用代码读系统模式后,应用内又想手动切换,结果互相打架、来回闪烁;
- 图片在深色背景下刺眼,缺乏对应的暗色资源。
细节解析
1. 资源限定词目录(首选,零代码)
HarmonyOS 的资源系统支持 dark 限定词。在 resources/ 下建立 dark/element/color.json,与 base/ 同名字段,框架会根据当前模式自动选择:
resources/
├─ base/element/color.json // 浅色值
└─ dark/element/color.json // 深色值
UI 里统一用 $r('app.color.background'),无需任何 if/else。
2. 监听系统色彩模式(代码兜底)
EntryAbility 的 onConfigurationUpdate 能感知系统颜色模式变化,把结果写入 AppStorage,页面用 @StorageProp 读取:
import { ConfigurationConstant } from '@kit.AbilityKit';
onConfigurationUpdate(config: Configuration) {
const isDark = config.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
AppStorage.setOrCreate('isDark', isDark);
}
3. 应用内手动切换(覆盖系统)
用 @StorageLink('isDark') 让页面既能读、也能写。用户手动切后写入 AppStorage,页面立即响应;若想"跟随系统",重新从 config 同步即可。
4. 图片与图标
深色模式优先用 SVG/矢量图;位图则准备 media 与 media/dark 两份,同样走资源限定词自动切换。
示例代码
// 1) resources/base/element/color.json
{ "color": [{ "name": "background", "value": "#FFFFFF" }, { "name": "text", "value": "#000000" }] }
// 2) resources/dark/element/color.json
{ "color": [{ "name": "background", "value": "#1A1A1A" }, { "name": "text", "value": "#E0E0E0" }] }
// 3) EntryAbility.ts
import { ConfigurationConstant } from '@kit.AbilityKit';
export default class EntryAbility extends UIAbility {
onConfigurationUpdate(config: Configuration) {
AppStorage.setOrCreate('isDark',
config.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK);
}
}
// 4) 页面
@Entry @Component
struct ThemePage {
@StorageLink('isDark') isDark: boolean = false;
build() {
Column() {
Text('当前主题:' + (this.isDark ? '深色' : '浅色'))
.fontColor($r('app.color.text'))
Button(this.isDark ? '切到浅色' : '切到深色')
.backgroundColor($r('app.color.background'))
.onClick(() => { this.isDark = !this.isDark; })
}
.width('100%').height('100%')
.backgroundColor($r('app.color.background'))
}
}
总结
- 颜色一律走
$r资源,用base+dark限定词实现零代码自动切换; - 系统模式变化用
onConfigurationUpdate写入AppStorage; - 手动切换用
@StorageLink读写同一份状态,避免与系统模式"打架"; - 图片用矢量或准备暗色资源,整体才协调。
遵循"资源为主、代码兜底"的原则,深色模式适配就不再是苦力活。
更多推荐



所有评论(0)