HarmonyOS 鸿蒙Next的深色模式该如何适配?
HarmonyOS 鸿蒙Next的深色模式该如何适配? HarmonyOS的深色模式该如何适配?有知指导吗?
更多关于HarmonyOS 鸿蒙Next的深色模式该如何适配?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
【问题背景】:HarmonyOS的深色模式该如何适配?
【解决思路】:
- 应用跟随系统的深浅色模式:应用颜色 / 资源随系统模式自动切换;
- 应用主动设置深浅色模式:应用固定某一模式,不随系统变化。
一、应用跟随系统深浅色模式
需从颜色、图片、组件、监听等维度实现适配,核心是通过 “资源配置” 或 “系统资源调用” 实现自动切换。
1. 颜色适配(两种实现方式)
| 实现方式 | 核心逻辑 | 代码示例核心片段 |
|---|---|---|
| 自定义资源 | 在resources目录下新增dark限定词目录,创建color.json,与基础目录同名配色设不同色值 |
基础目录:"app_title_color": "#000000";dark 目录:"app_title_color": "#FFFFFF" |
| 系统资源(推荐) | 直接调用系统预置资源(分层参数),同一资源 ID 随模式自动变值,保证视觉风格统一 | Text('文本').fontColor($r('sys.color.ohos_id_color_text_primary')) |
2. 图片资源适配
- 普通图片:在
dark/media目录放与基础目录同名的深色图片,通过$r('app.media.xxx')加载,系统自动切换; - SVG 图标:无需两套图片,通过
fillColor绑定系统资源实现颜色切换,示例:
Image($r('app.media.pic_svg')).width(50).fillColor($r('sys.color.ohos_id_color_text_primary'))。
3. 特殊组件适配
- Web 组件:需单独配置前端页面深色模式,参考 “Web 组件深色模式” 文档;
- 自定义节点(BuilderNode/ComponentContent):需手动传递系统环境变化事件,通过
updateConfiguration()触发全量更新,需在FrameCallback的onFrame()中调用更新逻辑。
4. 监听系统模式切换事件
无论是否跟随系统,该监听均生效,用于自定义资源初始化逻辑,分 4 步:
- 在
AbilityStage.onCreate()中,将当前颜色模式存入AppStorage:
AppStorage.setOrCreate('currentColorMode', this.context.config.colorMode); - 在
AbilityStage.onConfigurationUpdate()中,刷新AppStorage的模式值; - 在 Page 中用
@StorageProp + @Watch监听模式变化:
@StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number = ...; - 在
aboutToAppear()(初始化)和onColorModeChange()(切换时)中执行适配逻辑。
5. 局部深浅色适配
通过WithTheme组件设置局部模式(跟随系统 / 浅色 / 深色),作用范围内的组件样式将按指定模式读取资源,详情参考 “设置应用页面局部深浅色” 文档。
三、应用主动设置深浅色模式
应用默认跟随系统,若需固定模式,通过setColorMode接口实现:
- 固定为浅色模式(未适配深色时推荐,避免显示异常):
onCreate(): void {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT);
}
- 重置为跟随系统(全系统组件开发时,需显式设置以保证切换):
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET)。
四、系统判定应用深浅色模式的规则
- 优先级 1:应用主动调用
setColorMode,则以接口设置为准; - 优先级 2:未主动设置时:
- 若工程有
dark目录及深色资源,系统组件自动切深色; - 若无
dark目录资源,系统组件保持浅色。
- 若工程有
五、使用建议与注意事项
1. 推荐方法
- 跟随系统时,用
AbilityStage或Ability的监听回调,绑定状态变量执行业务逻辑,确保模式切换时逻辑生效。
2. 不推荐方法
- 避免在属性设置中通过函数判断模式(如
getResource()返回色值),因热更新场景下,属性代码可能不重新执行,导致适配失效,示例:
// 不推荐:依赖属性重新执行,可靠性低
getResource(): string { return colorMode === "dark" ? "#000000" : "#FFFFFF"; }
Button.backgroundColor(this.getResource())
六、优化深浅色模式切换开销(API 20+)
默认切换需全量重绘,性能随 UI 复杂度上升,可通过metadata配置开启高性能切换:
- 在
module.json5中新增配置:
"metadata": [
{ "name": "configColorModeChangePerformanceInArkUI", "value": "true" }
]
- 注意:开启前需确保所有 “函数适配深浅色” 的逻辑已整改(避免逻辑失效)。
七、反色能力快速适配(API 20+)
适用于存量代码多、需快速适配深色的场景,基于 “优化切换开销” 开启,通过反色算法自动调整颜色,无需大量资源配置:
- 核心接口:
OH_ArkUI_SetForceDarkConfig,支持系统默认反色 / 自定义反色算法,仅对 “非资源值设置的颜色属性” 生效(资源配置优先); - 调用要求:
- 需先加载
OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"); - 在 UI 线程、节点创建前调用;
- 仅进程级生效,不支持部分组件单独启用 / 禁用(如全局禁用则所有组件禁用);
- 需先加载
- 生效优先级:开发者深色资源 > 控件级反色算法 > 全局反色算法;
- 不支持场景:
DatePickerDialog/TimePickerDialog等无实体节点的组件、CAPI 创建的节点。
【官方文档示例详解】
【问题分析】
实现HarmonyOS的深色模式以下方式。
【技术方案】
-
颜色适配
-
自定义资源实现 resources目录下增加深色模式限定词目录(命名为dark)并新建color.json文件,可显示深色模式颜色资源的配置。详细请参考资源分类与访问。
图1 resources目录结构示意

例如,你可以在这两个color.json中定义同名配色定义并赋予不同的色值。
base/element/color.json文件:
{ "color": [ { "name": "app_title_color", "value": "#000000" } ] }
-
-
通过系统资源实现 开发者可直接使用的系统预置资源,即分层参数,同一资源ID在设备类型、深浅色等不同配置下有不同的取值。通过使用系统资源,不同的开发者可以开发出具有相同视觉风格的应用,不需要自定义两份颜色资源,在深浅色模式下也会自动切换成不同的颜色值。例如,开发者可调用系统资源中的文本主要配色来定义应用内文本颜色。
Text('使用系统定义配色') .fontColor($r('sys.color.ohos_id_color_text_primary'))
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
使用colorMode
使用环境变量获取colorMode
根据参考文档,系统存在深浅色两种显示模式,分为下面两种情况:
不是有快捷吗,
鸿蒙Next深色模式适配使用资源限定符和主题切换。在resources目录下创建dark.element和dark.pattern文件定义深色样式,通过"ohos:colorMode"属性配置。在Ability中使用setTheme()方法动态切换主题,或通过config.json配置系统跟随。使用@ohos.app.ability.common模块检测系统主题变化,调用onConfigurationUpdate回调更新界面。需为所有自定义组件定义深色模式下的颜色和图片资源。
在HarmonyOS Next中适配深色模式,主要通过资源管理和主题响应机制实现:
-
资源目录配置
在resources目录下分别创建:base/element/(默认主题)dark/element/(深色主题) 在对应目录中定义颜色值(如color.json)和样式,系统会根据主题自动切换。
-
动态颜色定义
使用资源引用符$color:定义颜色,例如:{ "color": [ { "name": "background_color", "value": "$color:ffffff" }, { "name": "text_primary", "value": "$color:000000" } ] }深色模式下在
dark/element/color.json中覆盖为深色值。 -
UI组件自适应
直接引用资源名的组件会自动响应主题变化:Text('示例文本') .fontColor($r('app.color.text_primary')) .backgroundColor($r('app.color.background_color')) -
手动监听主题变化
通过window.getLastWindow(ctx)获取窗口实例,监听colorModeChange事件:window.getLastWindow(ctx).on('colorModeChange', (newMode) => { // 根据newMode更新UI逻辑 }); -
深色模式标识
使用Configuration模块检测当前模式:import configuration from '[@ohos](/user/ohos).app.ability.Configuration'; const config: Configuration = context.config; const isDark = (config.colorMode === ColorMode.COLOR_MODE_DARK);
建议在开发阶段同时测试浅色/深色主题,确保文字对比度、图标清晰度等符合用户体验规范。具体可参考官方文档《暗色模式适配指导》。

