深色模式已成为系统标配,华为审核也会建议适配。NetLab 1.0.2 版本因审核建议新增了深色模式适配,本文分享具体做法。

一、适配原理

HarmonyOS 深色模式适配核心:颜色不硬编码,用资源引用。系统根据当前模式自动加载 light 或 dark 资源目录下的颜色。

资源目录结构:
resources/
├── base/              # 默认(浅色)
│   └── element/
│       └── color.json
├── dark/              # 深色模式
│   └── element/
│       └── color.json
└── light/             # 浅色模式(可选,base即浅色)
    └── element/
        └── color.json

二、定义颜色资源

2.1 浅色(base/element/color.json)

{
  "color": [
    { "name": "bg_main",       "value": "#FAFAFA" },
    { "name": "bg_card",       "value": "#FFFFFF" },
    { "name": "text_primary",  "value": "#0F172A" },
    { "name": "text_secondary","value": "#64748B" },
    { "name": "accent",        "value": "#0052FF" }
  ]
}

2.2 深色(dark/element/color.json)

{
  "color": [
    { "name": "bg_main",       "value": "#0F172A" },
    { "name": "bg_card",       "value": "#1E293B" },
    { "name": "text_primary",  "value": "#F1F5F9" },
    { "name": "text_secondary","value": "#94A3B8" },
    { "name": "accent",        "value": "#4D7CFF" }
  ]
}
💡
命名一致是关键:light 和 dark 的颜色 name 必须一致,系统按 name 匹配切换。value 不同实现深浅差异。

三、代码引用

// ❌ 错误:硬编码颜色,无法适配
.backgroundColor('#FFFFFF')

// ✅ 正确:资源引用,自动适配
.backgroundColor($r('app.color.bg_card'))
.fontColor($r('app.color.text_primary'))

所有颜色都用 $r('app.color.xxx') 引用,系统切换深色模式时自动加载 dark 目录的值。

四、图片适配

某些图片在深色背景下需要不同版本(如 logo),用资源限定目录:

resources/
├── base/media/
│   └── logo.png       # 浅色版
├── dark/media/
│   └── logo.png       # 深色版(反色或浅色logo)

引用方式不变:Image($r('app.media.logo')),系统自动切换。

五、测试验证

  1. 系统切换:设置 → 显示和亮度 → 深色模式 → 切换,应用应实时变色
  2. 跟随系统:设置"自动切换"(日出日落),验证自动适配
  3. 强制深色:DevEco Studio 预览器可切换 light/dark 预览
  4. 检查对比度:深色模式下文字与背景对比度需 ≥ 4.5:1(WCAG标准)
⚠️
常见问题:① 忘了适配某处硬编码颜色,深色下白字白底看不见 ② 图片背景透明,深色下不协调 ③ 状态栏/导航栏颜色未适配。

六、小结

  • 核心:颜色用 $r() 资源引用,不硬编码
  • base 目录放浅色,dark 目录放深色,name 一致 value 不同
  • 图片同样可用资源限定目录适配
  • 测试要覆盖系统切换、跟随自动、对比度检查