
文章目录前言一、资源文件的优先级规则二、项目的资源目录结构三、颜色资源详解3.1 base/element/color.json亮色默认3.2 dark/element/color.json暗色覆盖3.3 代码中使用四、多语言字符串详解4.1 base/element/string.json英文默认4.2 zh_CN/element/string.json中文覆盖4.3 代码中使用五、应用标签的多语言六、为什么项目强制了亮色模式七、支持更多语言带格式的字符串八、颜色资源设计原则总结前言一个好的应用应该手机开了暗色模式App 自动变暗手机语言改成英文App 自动说英文。HarmonyOS 的资源系统天然支持这些能力只要你按规范组织资源文件这些适配自动完成不需要写任何判断代码。这篇文章结合项目讲清楚暗色模式和多语言是怎么工作的以及项目为什么主动关闭了暗色模式以及关掉的代价是什么。项目预览一、资源文件的优先级规则HarmonyOS 加载资源时按照以下优先级从高到低查找语言地区限定 语言限定 主题限定 默认(base) 示例设备语言zh_CN暗色模式 查找顺序 1. zh_CN/dark/element/color.json 语言暗色 2. zh_CN/element/color.json 中文颜色 3. dark/element/color.json 暗色模式颜色 4. base/element/color.json 默认颜色← 最终兜底字符串的查找顺序1. zh_CN/element/string.json 中文字符串 2. base/element/string.json 英文默认字符串整个过程完全自动你只需要在对应目录下放好文件框架自动匹配。二、项目的资源目录结构resources/ ├── base/ # 默认资源兜底 │ └── element/ │ ├── color.json # 亮色模式颜色 │ └── string.json # 英文字符串 ├── dark/ # 暗色模式覆盖 │ └── element/ │ └── color.json # 暗色模式颜色只定义需要覆盖的 └── zh_CN/ # 中文覆盖 └── element/ └── string.json # 中文字符串覆盖英文默认三、颜色资源详解3.1 base/element/color.json亮色默认{color:[{name:start_window_background,value:#FFFFFF},{name:page_background,value:#F1F3F5},{name:gas_station_name_color,value:#182431},{name:gas_station_addr_color,value:#99182431},{name:bind_sheet_background,value:#FFFFFF}]}颜色格式#FFFFFF不透明白色标准 RGB#99182431带透明度#AARRGGBB99≈ 60% 不透明度182431是深蓝色3.2 dark/element/color.json暗色覆盖{color:[{name:start_window_background,value:#000000}]}暗色文件只定义需要变化的颜色没定义的自动用base/里的值。这里只覆盖了start_window_background黑色这意味着其他颜色page_background、文字颜色等在暗色模式下和亮色一样——这是项目有意为之的因为强制了亮色模式。3.3 代码中使用// 使用颜色资源引用自动适配亮色/暗色Column().backgroundColor($r(app.color.start_window_background))Text(站名).fontColor($r(app.color.gas_station_name_color))不需要任何判断系统自动选择对应的颜色。四、多语言字符串详解4.1 base/element/string.json英文默认{string:[{name:EntryAbility_label,value:nearby gas station},{name:gas_station,value:gas station},{name:car_life,value:car life},{name:nearby,value:vicinity},{name:navigation_text,value:Navigation},{name:calculate_text2,value:Km},{name:Stay_tuned,value:Stay tuned}]}4.2 zh_CN/element/string.json中文覆盖{string:[{name:EntryAbility_label,value:附近加油站},{name:gas_station,value:加油站},{name:car_life,value:汽车生活},{name:nearby,value:附近},{name:navigation_text,value:导航},{name:calculate_text2,value:公里},{name:Stay_tuned,value:敬请期待}]}4.3 代码中使用// 直接用资源引用语言自动切换Text($r(app.string.car_life))// 中文显示汽车生活英文显示car life// 获取字符串值用于逻辑处理letunitTextthis.getUIContext().getHostContext()?.resourceManager.getStringSync($r(app.string.calculate_text2).id);// 中文设备unitText 公里// 英文设备unitText Km五、应用标签的多语言string.json里有一个特殊的 keyEntryAbility_label这是应用显示在桌面上的名称。在module.json5里引用它{module:{abilities:[{name:EntryAbility,label:$string:EntryAbility_label// 引用字符串资源}]}}中文系统显示附近加油站英文系统显示nearby gas station就是这么配置的。六、为什么项目强制了亮色模式// EntryAbility.onCreate()this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT);这行代码让整个 App 强制使用亮色模式即使系统开了暗色App 也不跟着变暗。原因分析地图类应用有精心设计的配色方案以白色为主色调目前只设计了亮色主题暗色主题颜色没有仔细调整贸然跟随系统暗色可能导致 UI 不协调比如文字看不清代价暗色模式下这个 App 依然是亮色用户体验可能不一致dark/目录里定义的颜色不会生效因为强制了亮色正确做法如果要完整支持暗色删除setColorMode这行代码在dark/element/color.json里为所有颜色定义暗色版本测试每个页面在暗色模式下的显示效果七、支持更多语言如果想支持更多语言只需要添加对应的语言目录resources/ ├── base/element/string.json # 英文默认 ├── zh_CN/element/string.json # 中文简体 ├── zh_TW/element/string.json # 中文繁体 ├── ja/element/string.json # 日语 └── ko/element/string.json # 韩语每个目录里的string.json只需要定义那个语言的字符串翻译格式和base/完全一样。带格式的字符串如果字符串里有动态内容如用户名可以用占位符{name:welcome_message,value:欢迎%s}代码里用资源管理器格式化letmsgresourceManager.getStringByNameSync(welcome_message,[张三]);// 结果欢迎张三八、颜色资源设计原则设计暗色模式颜色时主要考虑场景亮色暗色主背景白色 (#FFFFFF)深灰 (#1A1A1A)卡片背景浅灰 (#F1F3F5)深色 (#2A2A2A)主要文字深色 (#182431)浅色 (#E8E8E8)次要文字透明深色 (#99182431)透明浅色 (#99E8E8E8)分割线浅灰 (#E5E5E5)深灰 (#3A3A3A)总结HarmonyOS 的资源适配系统非常强大暗色模式在dark/element/color.json里定义暗色颜色代码无感知自动切换多语言在zh_CN/element/string.json及其他语言目录定义翻译代码无感知资源引用用$r(app.color.xxx)和$r(app.string.xxx)不要硬编码颜色和文字优先级语言特定 主题特定 base 默认自动兜底项目强制亮色模式是一个设计决策代价是暗色用户的体验一致性。如果要完整支持暗色需要补全dark/目录里所有颜色的暗色版本并删除setColorMode强制代码。下一篇是最后一篇——项目总结与优化建议把整个系列串起来并给出实际项目中可以做的优化点。