鸿蒙原生开发手记:徒步迹 - 资源管理与多主题适配

学习鸿蒙资源系统,实现深色模式和主题切换


一、前言

资源管理是 App 国际化、多主题适配的基础。HarmonyOS 提供了完善的资源管理框架,支持多语言、多屏幕密度、深色/浅色模式等能力。

本文介绍"徒步迹"的资源结构设计、颜色主题系统以及深色模式的适配方案。


二、资源目录结构

resources/
├── base/                      # 基础资源(默认)
│   ├── element/
│   │   ├── string.json        # 字符串资源
│   │   ├── color.json         # 颜色资源
│   │   ├── float.json         # 浮点数资源
│   │   └── boolean.json       # 布尔资源
│   ├── media/                 # 图片资源
│   │   ├── app_icon.png
│   │   └── ...
│   ├── profile/               # 配置文件
│   │   └── main_pages.json
│   └── rawfile/               # 原始文件
├── en_US/                     # 英语(美国)
│   └── element/
│       └── string.json
├── zh_CN/                     # 简体中文
│   └── element/
│       └── string.json
└── dark/                      # 深色模式资源
    └── element/
        └── color.json

三、徒步迹的字符串资源

// resources/base/element/string.json
{
  "string": [
    {
      "name": "app_name",
      "value": "徒步迹"
    },
    {
      "name": "login_title",
      "value": "登录"
    },
    {
      "name": "home_title",
      "value": "首页"
    },
    {
      "name": "tracking_title",
      "value": "轨迹记录"
    },
    {
      "name": "health_title",
      "value": "健康数据"
    },
    {
      "name": "profile_title",
      "value": "个人中心"
    },
    {
      "name": "reason_location",
      "value": "用于记录徒步轨迹和显示当前位置"
    },
    {
      "name": "reason_camera",
      "value": "用于拍摄沿途风景照片"
    }
  ]
}

四、颜色体系与主题

4.1 定义颜色资源

// resources/base/element/color.json(浅色模式)
{
  "color": [
    { "name": "primary_color", "value": "#4CAF50" },
    { "name": "primary_dark", "value": "#388E3C" },
    { "name": "primary_light", "value": "#81C784" },
    { "name": "accent_color", "value": "#FF6F00" },
    { "name": "background_color", "value": "#F5F5F5" },
    { "name": "card_background", "value": "#FFFFFF" },
    { "name": "text_primary", "value": "#212121" },
    { "name": "text_secondary", "value": "#757575" },
    { "name": "divider_color", "value": "#E0E0E0" },
    { "name": "error_color", "value": "#F44336" },
    { "name": "success_color", "value": "#4CAF50" },
    { "name": "warning_color", "value": "#FF9800" }
  ]
}

4.2 深色模式适配

// resources/dark/element/color.json(深色模式)
{
  "color": [
    { "name": "background_color", "value": "#121212" },
    { "name": "card_background", "value": "#1E1E1E" },
    { "name": "text_primary", "value": "#E0E0E0" },
    { "name": "text_secondary", "value": "#9E9E9E" },
    { "name": "divider_color", "value": "#333333" }
  ]
}

4.3 在代码中使用颜色

// 使用 $r 引用资源
Text('徒步迹')
  .fontColor($r('app.color.primary_color'));     // 主色

Column()
  .backgroundColor($r('app.color.background_color')); // 背景色

Text('详细描述')
  .fontColor($r('app.color.text_secondary'));    // 次要文字

系统会自动根据当前主题模式加载对应资源。


五、国际化适配

5.1 中文资源

// resources/zh_CN/element/string.json
{
  "string": [
    { "name": "app_name", "value": "徒步迹" },
    { "name": "home_title", "value": "首页" },
    { "name": "tracking_title", "value": "轨迹记录" }
  ]
}

5.2 英文资源

// resources/en_US/element/string.json
{
  "string": [
    { "name": "app_name", "value": "Tuji" },
    { "name": "home_title", "value": "Home" },
    { "name": "tracking_title", "value": "Tracking" }
  ]
}

5.3 图片国际化

图片也可以按语言/地区放置:

resources/
├── base/media/     → 默认图片(所有语言共享)
├── zh_CN/media/    → 中文专用图片
└── en_US/media/    → 英文专用图片

六、运行时获取资源

// 通过 ResourceManager 获取资源
let context: Context = getContext(this);
let resMgr = context.resourceManager;

// 获取字符串(支持参数替换)
let appName = resMgr.getStringSync($r('app.string.app_name'));

// 获取布尔值
let isFeatureEnabled = resMgr.getBooleanSync($r('app.boolean.feature_enabled'));

// 获取浮点数
let cardRadius = resMgr.getNumberSync($r('app.float.card_radius'));

// 获取整型
let maxItems = resMgr.getNumberSync($r('app.integer.max_list_items'));

// 检查当前语言
let language = resMgr.getSystemLanguage();  // "zh-CN" / "en-US"

七、主题切换实现(深色模式)

// 在设置页面中控制深色模式
@Entry
@Component
struct SettingsPage {
  @State isDarkMode: boolean = false;

  aboutToAppear(): void {
    // 读取已保存的主题设置
    let preferences = getContext(this).resourceManager;
    // 实际开发中使用 Preferences 存储
  }

  build() {
    Column() {
      Row() {
        Text('深色模式')
          .fontSize(16)
          .layoutWeight(1);

        Toggle({ type: ToggleType.Switch, isOn: this.isDarkMode })
          .selectedColor($r('app.color.primary_color'))
          .onChange((isOn: boolean) => {
            this.isDarkMode = isOn;
            this.switchTheme(isOn);
          });
      }
      .width('100%')
      .padding(16);
    }
  }

  switchTheme(dark: boolean): void {
    // 通过系统API切换主题
    let windowClass = getContext(this).window;
    windowClass?.setWindowSystemBarProperties({
      isDarkMode: dark,
    });
  }
}

八、总结

资源管理是应用质量的重要体现,合理的资源结构让多语言、多主题适配变得简单。徒步迹的颜色体系和资源定义已经在项目中使用,后续页面开发中会不断复用这些资源。

下一篇文章将深入学习 ArkTS 状态管理,理解 @State、@Prop、@Link 等装饰器。


下一篇预告:鸿蒙原生开发手记:徒步迹 - @State/@Prop/@Link 状态管理

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐