鴻蒙學習實戰之路-HarmonyOS 資源分類與訪問指南

最近好多鴻蒙新手問我:"西蘭花,鴻蒙裏的資源文件怎麼管理啊?圖片、字符串、顏色這些東西都放哪兒?怎麼訪問?感覺比前端的資源管理複雜多了!"o(╯□╰)o

別急別急,今天這篇就帶你們搞定 HarmonyOS 的資源管理——就像咱們整理廚房調料一樣,鴻蒙也有它的"收納邏輯",學會了你會發現其實超簡單!


🥦 一、鴻蒙資源的"收納盒"分類

鴻蒙的資源文件就像咱們廚房裏的調料,得分類放好才好找。它把資源分成了這幾大類:

1. 元素資源(Element)

主要存放應用的配置信息和靜態數據:

  • 字符串(string):界面上的文字,多語言支持全靠它
  • 顏色(color):主題色、文字色這些
  • 尺寸(float):字體大小、間距這些數值
  • 布爾值(boolean):開關狀態
  • 數組(array):一組相關數據

2. 媒體資源(Media)

存放界面上用到的各種媒體文件:

  • 圖片(png/jpg/svg 等):界面上的圖標、背景圖
  • 音頻(mp3 等):提示音、背景音樂
  • 視頻(mp4 等):宣傳視頻啥的

3. 佈局資源(Layout)

使用 XML 格式描述界面結構的佈局文件:

4. 動畫資源(Animation)

定義動畫效果的 JSON 配置文件:

5. 原始文件(RawFile)

這個厲害了!鴻蒙會原封不動地打包這些文件,支持任何格式:

  • 配置文件(json/xml)
  • 字體文件(ttf/otf)
  • 文檔(pdf 等)

鴻蒙學習實戰之路-HarmonyOS 資源分類與訪問指南_多語言

🥦 二、資源文件的"擺放位置"

鴻蒙項目的資源都住在entry/src/main/resources目錄下,咱們來看看具體怎麼放:

resources/
├── base/              # 基礎資源目錄
│   ├── element/       # 元素資源
│   ├── media/         # 媒體資源
│   ├── layout/        # 佈局資源
│   ├── animation/     # 動畫資源
│   └── rawfile/       # 原始文件
├── en_US/             # 英文資源(多語言)
├── zh_CN/             # 中文資源(多語言)
└── values-sw600dp/    # 大屏設備資源(適配不同尺寸)

是不是超靈活?可以根據設備類型、分辨率、語言等多種維度來組織資源!

🥦 三、怎麼訪問這些資源?

放好了資源,咱們得知道怎麼在代碼裏用啊!鴻蒙提供了兩種主要的訪問方式:

鴻蒙學習實戰之路-HarmonyOS 資源分類與訪問指南_多語言_02

1. 資源引用($r)

這是最常用的方式,通過資源 ID 統一訪問各種資源。

代碼示例:

// 訪問字符串資源
Text($r('app.string.hello_world'))
  .fontSize($r('app.float.title_size'))  // 訪問尺寸資源
  .fontColor($r('app.color.primary_color'))  // 訪問顏色資源

// 訪問圖片資源
Image($r('app.media.logo'))
  .width(100)
  .height(100)

這裏的app是資源的命名空間,string/media是資源類型,hello_world/logo是資源名。是不是超直觀?

鴻蒙學習實戰之路-HarmonyOS 資源分類與訪問指南_多語言_03

2. 原始文件訪問(ResourceManager)

對於 rawfile 目錄下的文件,咱們得用 ResourceManager 來訪問。

代碼示例:

// 獲取ResourceManager實例
let resourceManager = getContext(this).resourceManager;

// 讀取文本文件
resourceManager.getRawFileContent('config.json').then((content) => {
  let config = JSON.parse(String.fromCharCode.apply(null, new Uint8Array(content)));
  console.log('配置文件內容:' + JSON.stringify(config));
});

// 讀取圖片文件
resourceManager.getRawFileContent('custom_image.png').then((content) => {
  let imageSource = image.createImageSource();
  imageSource.createPixelMap(content).then((pixelMap) => {
    // 使用pixelMap創建圖片
  });
});

鴻蒙的 API 是 Promise 風格的,用起來超現代!

🥦 四、多語言與適配,就這麼簡單!

鴻蒙的資源適配能力超級強,超直觀:

1. 多語言支持

resources目錄下創建對應語言的文件夾(如en_USzh_CN),然後在每個文件夾裏放對應的element/string.json,系統會自動根據設備語言選擇資源。

鴻蒙學習實戰之路-HarmonyOS 資源分類與訪問指南_資源文件_04

示例:

  • resources/zh_CN/element/string.json:中文字符串
  • resources/en_US/element/string.json:英文字符串

2. 設備適配

通過"限定詞目錄"來適配不同設備,比如:

  • values-sw600dp:屏幕寬度大於 600dp 的設備
  • values-land:橫屏模式
  • media-xxhdpi:高分辨率屏幕的圖片

系統會根據當前設備狀態自動匹配最合適的資源,是不是超靈活?

鴻蒙學習實戰之路-HarmonyOS 資源分類與訪問指南_json_05

🥦 五、實戰:做個帶多語言的登錄界面

光説不練假把式,咱們來整個實戰 Demo——帶多語言支持的登錄界面:

1. 準備資源文件

字符串資源(中文)resources/zh_CN/element/string.json

{
  "string": [
    {
      "name": "app_name",
      "value": "我的鴻蒙應用"
    },
    {
      "name": "login_title",
      "value": "用户登錄"
    },
    {
      "name": "username_hint",
      "value": "請輸入用户名"
    },
    {
      "name": "password_hint",
      "value": "請輸入密碼"
    },
    {
      "name": "login_button",
      "value": "登錄"
    }
  ]
}

字符串資源(英文)resources/en_US/element/string.json

{
  "string": [
    {
      "name": "app_name",
      "value": "My Harmony App"
    },
    {
      "name": "login_title",
      "value": "User Login"
    },
    {
      "name": "username_hint",
      "value": "Enter username"
    },
    {
      "name": "password_hint",
      "value": "Enter password"
    },
    {
      "name": "login_button",
      "value": "Login"
    }
  ]
}

顏色資源resources/base/element/color.json

{
  "color": [
    {
      "name": "primary_color",
      "value": "#007AFF"
    },
    {
      "name": "text_color",
      "value": "#333333"
    },
    {
      "name": "hint_color",
      "value": "#999999"
    }
  ]
}

尺寸資源resources/base/element/float.json

{
  "float": [
    {
      "name": "title_size",
      "value": "24fp"
    },
    {
      "name": "input_size",
      "value": "16fp"
    },
    {
      "name": "spacing",
      "value": "20fp"
    }
  ]
}

2. 編寫登錄界面代碼

import promptAction from '@ohos.promptAction';

@Entry
@Component
struct LoginPage {
  @State username: string = '';
  @State password: string = '';

  build() {
    Column({
      space: $r('app.float.spacing')
    }) {
      // 應用圖標
      Image($r('app.media.app_icon'))
        .width(100)
        .height(100)
        .margin({ top: 60 })

      // 標題
      Text($r('app.string.login_title'))
        .fontSize($r('app.float.title_size'))
        .fontColor($r('app.color.text_color'))
        .fontWeight(FontWeight.Bold)
        .margin({ top: 40 })

      // 用户名輸入框
      TextInput({
        placeholder: $r('app.string.username_hint'),
        text: this.username
      })
        .width('80%')
        .height(50)
        .fontSize($r('app.float.input_size'))
        .fontColor($r('app.color.text_color'))
        .placeholderColor($r('app.color.hint_color'))
        .backgroundColor('#F5F5F5')
        .borderRadius(8)
        .padding({ left: 15 })
        .onChange((value: string) => {
          this.username = value;
        })

      // 密碼輸入框
      TextInput({
        placeholder: $r('app.string.password_hint'),
        text: this.password,
        type: InputType.Password
      })
        .width('80%')
        .height(50)
        .fontSize($r('app.float.input_size'))
        .fontColor($r('app.color.text_color'))
        .placeholderColor($r('app.color.hint_color'))
        .backgroundColor('#F5F5F5')
        .borderRadius(8)
        .padding({ left: 15 })
        .onChange((value: string) => {
          this.password = value;
        })

      // 登錄按鈕
      Button($r('app.string.login_button'))
        .width('80%')
        .height(50)
        .fontSize($r('app.float.input_size'))
        .fontColor(Color.White)
        .backgroundColor($r('app.color.primary_color'))
        .borderRadius(8)
        .margin({ top: 20 })
        .onClick(() => {
          if (this.username && this.password) {
            promptAction.showToast({
              message: '登錄成功!',
              duration: 2000
            });
          } else {
            promptAction.showToast({
              message: '請輸入用户名和密碼',
              duration: 2000
            });
          }
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor(Color.White)
    .alignItems(HorizontalAlign.Center)
  }
}

3. 代碼解析

  • 咱們用$r()引用了各種資源,統一管理超方便
  • 多語言支持是自動的,切換設備語言就能看到效果
  • 顏色和尺寸都用了資源文件,以後改主題色只需要改color.json就行,不用改代碼!

🥦 西蘭花警告

  • 資源命名不能有大寫字母:鴻蒙的資源名必須是小寫字母加下劃線,否則編譯報錯(別問我怎麼知道的_
  • rawfile 目錄下的文件不會被壓縮:圖片這類資源最好放 media 目錄,系統會自動優化
  • 多語言資源要保持 key 一致:不同語言的 string.json 裏的 name 字段必須完全一樣,否則會找不到資源

🥦 西蘭花小貼士

  • ohpm install @ohos/resourcemanager可以獲取更強大的資源管理能力
  • 資源文件可以用 DevEco Studio 的可視化編輯器編輯,比手動寫 JSON 方便多了
  • 複雜的佈局可以用 XML 寫在 layout 目錄,然後在 ArkTS 裏引用

🥦 總結一下

HarmonyOS 的資源管理核心思路就是"分類存放+統一訪問":

  • 分類存放:把不同類型的資源(文字、顏色、圖片等)放在不同的目錄下,就像整理廚房調料一樣
  • 統一訪問:通過$r()ResourceManager訪問資源,不管資源具體放在哪裏
  • 智能適配:系統自動根據設備狀態匹配最合適的資源,多語言、多設備適配超簡單

現在你們應該能輕鬆搞定鴻蒙的資源文件了吧?學會這套"收納邏輯",咱們也能把鴻蒙的資源管理得井井有條!

👉 下一步行動

  1. 打開 DevEco Studio,創建一個測試項目,試試今天學的資源管理
  2. 把你的項目資源按照鴻蒙的分類方式整理一下
  3. 嘗試做一個多語言切換的小功能,鞏固今天的知識

📚 推薦資料

  • 官方資源管理文檔:華為開發者文檔-資源分類與訪問
  • 多語言開發指南:華為開發者文檔-應用

我是鹽焗西蘭花, 不教理論,只給你能跑的代碼和避坑指南。 下期見!🥦