HarmonyOS 鸿蒙Next中系统一开暗色模式页面全花了?ArkUI 颜色适配从硬编码到系统联动
HarmonyOS 鸿蒙Next中系统一开暗色模式页面全花了?ArkUI 颜色适配从硬编码到系统联动 项目快上线了才发现暗色模式完全没适配,打开系统暗色模式之后:
- 页面背景还是白色,但系统状态栏文字变成了白色,顶部直接看不见
- 有些 Text 组件的文字颜色写死成 Color.Black,暗色模式下背景变深色,文字跟背景融为一体
- SVG 图标是深色的,暗色模式下在深色背景上几乎看不见
更多关于HarmonyOS 鸿蒙Next中系统一开暗色模式页面全花了?ArkUI 颜色适配从硬编码到系统联动的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
可以看下我的实战案例:如何给自己的应用适配深浅主题模式?【案例示例】
-
当系统切换到深色模式后,应用内可能会出现部分内容切换到深色主题的情况,例如状态栏、弹窗背景色、系统控件等,会导致应用内页面效果错乱。
为应对上述情况,需要对应用进行深色模式下的内容适配,目前该适配主要依靠资源目录。当系统对应的设置项发生变化后(如系统语言、深浅色模式等),应用会自动加载对应资源目录下的资源文件。

相关文档:【应用深浅色适配】
学到了
背景知识:
鸿蒙系统明暗色模式切换原理
- 系统分为两套全局资源集:base(默认亮色)、dark(暗色专属);系统切换深色模式后,应用会优先加载dark目录下同路径资源、颜色、图片;
- 状态栏文字颜色自动跟随系统主题:亮色状态栏黑字、暗色状态栏白字。如果页面根背景仍是白色,白色状态栏文字直接融合看不见,就是你第一个问题;
- 硬编码写死颜色Color.Black、固定深色 SVG 图标,不会随系统主题自动切换,暗色模式下对比度失效,文字 / 图标消失;
- 核心错误根源:
- 全部颜色、图片直接写死硬编码,未使用系统主题资源色;
- 未创建dark暗色资源目录;
- 页面未设置自适应根背景,状态栏未适配沉浸主题色;
- 未开启应用跟随系统深色模式开关。
问题解决:
1、两套全局资源集:

创建不同模式下的资源
2、状态栏文字颜色自动跟随系统主题
import uiAppearance from '@ohos.uiAppearance';
// 获取当前是否暗色模式
function isDarkMode(): boolean {
const scheme = uiAppearance.getDarkMode();
return scheme === uiAppearance.DarkMode.ALWAYS_DARK;
}
// 动态设置状态栏
this.windowStage.getMainWindow().setWindowSystemBarProperties({
statusBarFontColor: isDarkMode() ? "#ffffff" : "#000000"
})
3、硬编码写死颜色Color.Black、固定深色 SVG 图标
//text的颜色直接使用 上面的base 和 dark
Text("主标题")
.fontColor($r('app.color.text_main'))
Text("辅助说明")
.fontColor($r("sys.color.text_secondary"))
// base/element/color.json
{
"name": "text_main",
"value": "#000000"
}
//dark/element/color.json
{
"name": "text_main",
"value": "#ffffff"
}
//使用矢量图标主题色填充
Image($r("sys.media.icon_home"))
.width(24)
.height(24)
//亮色图标:resources/base/media/icon_home.svg(黑色)
//暗色图标:resources/dark/media/icon_home.svg(白色)
mark
这个不是单个组件 bug,更像是颜色体系没有语义化:页面背景、文字、图标、系统栏各写各的固定色,系统切到暗色后就互相“撞色”了。建议先把硬编码颜色收口到资源,再让资源按浅色/深色切换。
可按这几步改:
- 不要继续写
Color.Black、Color.White、'#000000'这类固定色。页面颜色改成语义资源:
// resources/base/element/color.json
{
"color": [
{ "name": "page_bg", "value": "#FFFFFF" },
{ "name": "text_primary", "value": "#182431" },
{ "name": "icon_primary", "value": "#182431" }
]
}
// resources/dark/element/color.json
{
"color": [
{ "name": "page_bg", "value": "#101014" },
{ "name": "text_primary", "value": "#E5E5E5" },
{ "name": "icon_primary", "value": "#E5E5E5" }
]
}
- 组件里只引用资源:
Column() {
Text('标题').fontColor($r('app.color.text_primary'))
Image($r('app.media.ic_back')).fillColor($r('app.color.icon_primary'))
}
.backgroundColor($r('app.color.page_bg'))
-
SVG 图标分两类处理:单色图标用
Image.fillColor($r('app.color.icon_primary'))统一着色;多色图标不要强行fillColor,准备深浅色两套资源或把 SVG 内部颜色整理成标准写法。 -
状态栏要和顶部背景一起处理。顶部是浅色就用深色状态栏文字,顶部是深色就用浅色状态栏文字;不要只改页面背景,不同步系统栏内容色。
排查时可以先全局搜 Color.Black、Color.White、#000、#fff,把这些点逐个替换成语义色。官方 Code Linter 的 color-value 规则也建议颜色通过 $r 从 color.json 引用,以适配不同系统颜色模式。
依据:Code Linter @cross-device-app-dev/color-value 规则、ArkUI 颜色资源适配说明。
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-code-linter
这个问题在实际项目里很常见,很多项目开发阶段只测了浅色模式,最后一开暗色模式整个页面“炸了”。
根本原因一般是:页面颜色写死,没有走系统主题资源适配。
1、不要直接写死颜色
比如:
Text('标题')
.fontColor(Color.Black)
暗色模式:
背景变深色
文字还是 Black
自然看不见。
建议改成资源颜色:
Text('标题')
.fontColor($r('app.color.text_primary'))
然后:
{
"text_primary": {
"value": "#000000"
}
}
dark目录:
resources/
├ base/element/color.json
└ dark/element/color.json
dark里面:
{
"text_primary": {
"value": "#FFFFFF"
}
}
系统切换时会自动替换。
2、背景不要固定白色
例如:
.background('#FFFFFF')
暗色下就会出现:
背景白 + 状态栏白字。
改:
.background($r('app.color.page_bg'))
浅色:
#FFFFFF
深色:
#000000
3、状态栏颜色也要同步
页面背景变暗,但是状态栏还是系统判断颜色,很容易:
白底 + 白字
或者:
黑底 + 黑字
需要根据主题设置:
window.setWindowSystemBarProperties({
statusBarColor: bgColor,
statusBarContentColor: isDark
? 'light'
: 'dark'
})
4、SVG图标也是高频坑
很多 SVG:
fill="#000000"
暗色背景:
黑图标直接消失。
建议:
- 使用多套资源
- 或使用 tint 动态着色
比如:
light:
icon_black.svg
dark:
icon_white.svg
资源目录区分。
5、全局排查建议
项目里搜索:
#FFFFFF
#000000
Color.Black
Color.White
这些基本都是暗色风险点。
实际项目推荐:
不要组件自己决定颜色
应该:
主题资源 → 组件引用 → 系统切换自动适配
流程:
系统暗色切换
→ resources dark 生效
→ ArkUI重新渲染
这样后期不会一个页面一个页面补。
希望可以帮到你~~~~
单独建立一个theme 文件,定义一下项目各个元素的颜色吧,而且反复测试很重要,还有中英文的适配,就连很多大公司的适配也是如此,特别是英文界面上,蹦出好多中文来。
请提供需要转换的HTML内容。
暗色模式页面花屏源于硬编码颜色不随系统切换。ArkUI应使用$r('sys.color.*')系统颜色资源或定义color.json并配置dark限定词资源,使颜色自动跟随暗色模式。避免在代码中直接写固定色值。

