鸿蒙 应用适配深浅色模式
摘要:HarmonyOS支持应用适配深浅色模式,分为跟随系统自动切换和主动设置固定模式两种方式。适配要点包括:1)通过资源限定词目录(dark/)和系统预置资源实现颜色适配;2)使用WithTheme容器实现局部适配;3)通过onConfigurationUpdate监听模式变化;4)API20+支持高性能切换和反色能力优化。建议优先使用系统资源和状态变量绑定,避免性能损耗大的实现方式。适配时需注
本文同步发表于 微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
HarmonyOS 支持深浅色两种显示模式。为提升用户体验,应用应适配深浅色模式。适配分为两种情况:
-
应用跟随系统的深浅色模式:应用随系统自动切换。
-
应用主动设置深浅色模式:应用固定为某种模式,不随系统变化。
二、应用跟随系统的深浅色模式
2.1 颜色适配
2.1.1 自定义资源实现
-
在
resources目录下创建深色模式限定词目录dark,并在其中创建color.json文件,定义深色模式颜色 -
在
base/element/color.json中定义浅色颜色,在dark/element/color.json中定义深色颜色
示例:
// base/element/color.json
{
"color": [
{
"name": "app_title_color",
"value": "#000000"
}
]
}
// dark/element/color.json
{
"color": [
{
"name": "app_title_color",
"value": "#FFFFFF"
}
]
}
2.1.2 通过系统资源实现
-
使用系统预置资源(分层参数),如
$r('sys.color.ohos_id_color_text_primary') -
系统自动根据深浅色模式切换颜色值,无需自定义两份资源
示例:
Text('使用系统定义配色')
.fontColor($r('sys.color.ohos_id_color_text_primary'))
2.2 图片资源适配
-
使用资源限定词目录:深色模式图片放在
dark/media目录 -
通过
$r('app.media.pic_svg')加载图片,系统自动切换 -
SVG 图标可使用
fillColor配合系统资源改变颜色
示例:
Image($r('app.media.pic_svg'))
.width(50)
.fillColor($r('sys.color.ohos_id_color_text_primary'))
2.3 Web组件适配
-
Web组件支持深色模式配置,参考 Web组件深色模式
2.4 自定义节点适配
-
BuilderNode和ComponentContent需手动传递系统环境变化事件 -
使用
updateConfiguration()触发节点更新
示例:
const builderNodeMap: BuilderNode<[Params]>[] = [];
class MyFrameCallback extends FrameCallback {
onFrame() {
updateColorMode();
}
}
function updateColorMode() {
builderNodeMap.forEach((value) => {
value.updateConfiguration();
});
}
aboutToAppear(): void {
this.getUIContext()?.postFrameCallback(new MyFrameCallback());
}
2.5 应用监听深浅色模式切换事件
-
无论应用是否跟随系统,均可通过
onConfigurationUpdate监听 -
若应用使用
setColorMode手动设置深浅色,则不会收到该回调
步骤:
-
在
AbilityStage的onCreate中保存当前颜色模式到AppStorage。 -
在
onConfigurationUpdate中更新颜色模式。 -
在页面中使用
@StorageProp+@Watch监听变化。
示例:
// AbilityStage.ets
onCreate(): void {
AppStorage.setOrCreate('currentColorMode', this.context.config.colorMode);
}
onConfigurationUpdate(newConfig: Configuration): void {
AppStorage.setOrCreate('currentColorMode', newConfig.colorMode);
}
// Page.ets
@StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
aboutToAppear(): void {
if (this.currentMode == ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT) {
// 浅色模式初始化
} else {
// 深色模式初始化
}
}
onColorModeChange(): void {
// 同 aboutToAppear 逻辑
}
2.6 局部深浅色适配
-
使用
WithTheme容器设置局部颜色模式:-
ColorMode.SYSTEM:跟随系统 -
ColorMode.LIGHT:固定浅色 -
ColorMode.DARK:固定深色
-
-
作用域内组件根据指定模式读取对应资源。
三、应用主动设置深浅色模式
-
使用
setColorMode接口固定应用模式,不随系统变化 -
适用于未适配深色模式的应用,可固定为浅色
示例:
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT);
}
四、系统判定应用深浅色模式的规则
-
应用调用
setColorMode:以接口设置为准。 -
应用未调用
setColorMode:-
若
dark目录下有深色资源,则深色模式下自动切换。 -
若
dark目录下无资源,则深色模式下仍保持浅色。
-
强制跟随系统示例:
onCreate(): void {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
AppStorage.setOrCreate('currentColorMode', this.context.config.colorMode);
}
五、建议与注意事项
5.1 建议方法
-
使用
AbilityStage或Ability的onConfigurationUpdate监听变化 -
通过状态变量绑定资源,在回调中更新
5.2 不推荐方法
-
避免在属性设置中通过函数返回值切换颜色,如:
getResource(): string {
if (colorMode == "dark") {
return "#FF000000";
} else {
return "#FFFFFFFF";
}
}
-
这种方式依赖全量重绘,性能不可靠
5.3 优化深浅色模式切换开销(API 20+)
-
在
module.json5中配置metadata开启高性能切换:
"metadata": [
{
"name": "configColorModeChangePerformanceInArkUI",
"value": "true"
}
]
-
开启后需适配以下场景:
-
实时读取深浅色模式返回不同资源值 → 使用监听回调更新状态变量
-
自定义主题模式 → 绑定状态变量,在回调中更新
-
读取成员变量值返回不同资源值 → 绑定状态变量,在回调中更新
-
5.4 高级组件适配
-
HdsNavigation、HdsNavDestination、HdsTabs、HdsListItemCard暂未适配高性能切换,需使用onConfigurationUpdate回调处理颜色属性
六、利用反色能力快速适配深色模式(API 20+)
-
适用于已有部分适配的存量代码,通过反色算法快速实现全量适配
-
需开启“优化深浅色模式切换开销”
6.1 使用反色能力
-
调用
OH_ArkUI_SetForceDarkConfig接口,在 UI 线程中、节点创建前调用 -
支持自定义反色算法,默认算法为三原色取反
示例:
// CAPI 示例
OH_ArkUI_SetForceDarkConfig(nullptr, true, ArkUI_NodeType::ARKUI_NODE_UNDEFINED, nullptr);
// ArkTS 侧使用
Text("测试反色算法")
.fontColor(Color.Black) // 深色模式下自动反色为白色
6.2 接口入参效果
-
OH_ArkUI_SetForceDarkConfig(nullptr, true, ArkUI_NodeType::ARKUI_NODE_UNDEFINED, nullptr):所有组件使用默认反色算法 -
OH_ArkUI_SetForceDarkConfig(nullptr, false, ArkUI_NodeType::ARKUI_NODE_UNDEFINED, nullptr):所有组件停用反色能力 -
支持针对特定组件类型启用或自定义算法
6.3 反色算法优先级
-
深色模式颜色资源配置
-
指定组件的自定义反色算法
-
所有组件的自定义反色算法
6.4 反色能力逃生通道(API 21+)
-
可通过
allowForceDark属性禁用指定组件的自动反色能力
总结
-
适配深浅色模式分为跟随系统和主动设置两种
-
推荐使用系统资源、资源限定词目录、监听回调等方式实现
-
API 20+ 支持高性能切换和反色能力,可大幅降低适配成本和性能开销
-
需注意高级组件和反色能力的适配限制
更多推荐



所有评论(0)