HarmonyOS 鸿蒙Next 6如何实现应用国际化(多语言 + 区域适配)?
HarmonyOS 鸿蒙Next 6如何实现应用国际化(多语言 + 区域适配)?
问题描述
在鸿蒙 6(API20)应用中,需要支持中文(默认)、英文、日语三种语言,实现:1. 字符串国际化(如按钮文本、提示信息);2. 图片国际化(不同语言显示不同图片);3. 区域适配(如日期格式、数字单位)。如何配置资源文件并实现语言动态切换,且适配鸿蒙 6 的资源管理规范?关键字:鸿蒙 6、国际化、多语言、区域适配、资源文件、动态切换、API20
3 回复
一、原理解析
鸿蒙 6 的国际化基于「资源文件目录分级」和「系统语言检测」,核心机制:
- 资源文件按语言 / 区域划分目录(如
en/ja对应英文 / 日语),系统自动根据当前语言加载对应资源; - 字符串国际化通过
$r('app.string.xxx')引用,图片国际化通过$r('app.media.xxx')引用; - 动态切换语言需通过
resourceManager手动指定语言,并重载页面资源。
二、完整实现步骤
步骤 1:配置国际化资源文件
1. 目录结构(重点)
src/main/resources/
├── base/ // 默认资源(中文)
│ ├── element/
│ │ └── string.json // 中文字符串
│ └── media/ // 中文图片资源
│ ├── logo.png
│ └── background.png
├── en/ // 英文资源
│ ├── element/
│ │ └── string.json // 英文字符串
│ └── media/ // 英文图片资源
│ ├── logo.png
│ └── background.png
└── ja/ // 日语资源
├── element/
│ └── string.json // 日语字符串
└── media/ // 日语图片资源
├── logo.png
└── background.png
2. 字符串资源文件示例
base/element/string.json(中文):{ "string": [ { "name": "app_name", "value": "鸿蒙国际化示例" }, { "name": "login_btn", "value": "登录" }, { "name": "welcome_msg", "value": "欢迎使用本应用" }, { "name": "date_format", "value": "yyyy年MM月dd日" } ] }en/element/string.json(英文):{ "string": [ { "name": "app_name", "value": "HarmonyOS I18N Demo" }, { "name": "login_btn", "value": "Login" }, { "name": "welcome_msg", "value": "Welcome to the app" }, { "name": "date_format", "value": "MM/dd/yyyy" } ] }ja/element/string.json(日语):{ "string": [ { "name": "app_name", "value": "ハーモニーOS国際化デモ" }, { "name": "login_btn", "value": "ログイン" }, { "name": "welcome_msg", "value": "アプリへようこそ" }, { "name": "date_format", "value": "yyyy年MM月dd日" } ] }
步骤 2:组件中使用国际化资源
import resourceManager from '@ohos.resourceManager';
import common from '@ohos.app.ability.common';
import router from '@ohos.router';
import { BusinessError } from '@ohos.base';
@Entry
@Component
struct I18NDemo {
private context = getContext(this) as common.UIAbilityContext;
@State currentLanguage: string = 'zh'; // 当前语言:zh/en/ja
@State currentDate: string = '';
build() {
Column({ space: 30 })
.width('100%')
.height('100%')
.padding(20)
.justifyContent(FlexAlign.Center) {
// 国际化图片
Image($r('app.media.logo'))
.width(100)
.height(100)
// 国际化字符串
Text($r('app.string.welcome_msg'))
.fontSize(20)
Text(this.currentDate)
.fontSize(16)
// 语言切换按钮
Flex({ space: 10, justifyContent: FlexAlign.Center }) {
Button('中文')
.onClick(() => this.switchLanguage('zh'))
.backgroundColor(this.currentLanguage === 'zh' ? '#54A0FF' : '#CCCCCC')
Button('English')
.onClick(() => this.switchLanguage('en'))
.backgroundColor(this.currentLanguage === 'en' ? '#54A0FF' : '#CCCCCC')
Button('日本語')
.onClick(() => this.switchLanguage('ja'))
.backgroundColor(this.currentLanguage === 'ja' ? '#54A0FF' : '#CCCCCC')
}
Button($r('app.string.login_btn'))
.width('80%')
}
}
// 切换语言
private async switchLanguage(lang: string) {
this.currentLanguage = lang;
// 1. 设置资源管理器的语言
const rm = this.context.resourceManager;
await rm.setPreferredLanguage([lang]);
// 2. 重新加载页面资源(通过状态更新触发)
this.updateDate();
}
// 格式化日期(区域适配)
private updateDate() {
const date = new Date();
const format = $r('app.string.date_format').value;
this.currentDate = format.replace('yyyy', date.getFullYear().toString())
.replace('MM', (date.getMonth() + 1).toString().padStart(2, '0'))
.replace('dd', date.getDate().toString().padStart(2, '0'));
}
aboutToAppear() {
// 页面加载时获取系统当前语言
this.getCurrentSystemLanguage();
this.updateDate();
}
// 获取系统当前语言
private async getCurrentSystemLanguage() {
const rm = this.context.resourceManager;
const langs = await rm.getPreferredLanguage();
this.currentLanguage = langs[0] || 'zh';
}
}
步骤 3:配置 module.json5(声明支持的语言)
{
"module": {
"name": "entry",
"type": "entry",
"compileSdkVersion": 20,
"targetSdkVersion": 20,
"minSdkVersion": 20,
"supportedLanguages": ["zh", "en", "ja"], // 声明支持的语言
"abilities": [
// 能力配置...
]
}
}
三、避坑点
- 资源目录命名规范:语言目录必须使用 ISO 639-1 标准缩写(如
en/ja),区域目录用en_US/zh_CN格式; - 资源引用方式:必须用
$r('app.xxx.xxx')引用,不可硬编码字符串 / 图片路径; - 动态切换生效:切换语言后需通过状态更新触发组件重绘,或调用
router.replaceUrl重载页面; - 图片资源一致性:不同语言目录下的图片文件名必须一致,否则会导致加载失败;
- 系统语言适配:应用未声明的语言,系统会自动 fallback 到
base目录的默认资源。
更多关于HarmonyOS 鸿蒙Next 6如何实现应用国际化(多语言 + 区域适配)?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next 6应用国际化主要通过资源文件与API实现。在resources目录下按语言(如zh-CN)和区域建立子目录,存放string.json等资源文件。使用$r('app.string.xxx')引用字符串。系统API(如Intl)可处理日期、数字等本地化格式。应用运行时自动匹配用户设备语言与区域设置加载对应资源。
在HarmonyOS Next(API 20)中实现应用国际化,需遵循其资源管理框架。以下是针对您需求的实现方案:
1. 字符串国际化
- 资源文件位置:在
resources目录下,按语言创建element子目录,如:resources/zh/element/string.json(默认中文)resources/en-US/element/string.json(英文)resources/ja/element/string.json(日语)
- 内容格式:每个
string.json文件内定义键值对,例如:{ "string": [ { "name": "welcome_message", "value": "Welcome" } ] } - 代码调用:使用
$r('app.string.welcome_message')或资源管理API获取。
2. 图片等媒体资源国际化
- 资源文件位置:在对应语言的
media目录下放置同名图片,如:resources/zh/media/icon.pngresources/en-US/media/icon.png
- 系统自动匹配:引用
$r('app.media.icon')时,系统会根据当前语言自动加载对应目录下的图片。
3. 区域格式适配(日期/数字)
- 使用国际化API:直接调用
I18n模块的相关类,无需手动配置格式规则。- 日期格式化:使用
Intl.DateTimeFormat。let formatter = new Intl.DateTimeFormat('en-US', { dateStyle: 'full' }); console.log(formatter.format(new Date())); - 数字格式化:使用
Intl.NumberFormat。let numberFormat = new Intl.NumberFormat('ja-JP'); console.log(numberFormat.format(1234567.89)); - 其他:
Intl.Collator(字符串比较)、Intl.RelativeTimeFormat(相对时间)等。
- 日期格式化:使用
4. 实现语言动态切换
- 核心API:使用
resourceManager.getResourceManager获取指定语言区域的资源管理器,然后通过updateConfiguration更新应用配置。 - 关键步骤:
- 准备目标语言(如
"en-US")的资源管理器。 - 调用
context.updateConfiguration更新应用全局配置。 - 通常需要重启页面或应用来使新的字符串资源生效(媒体资源可能自动更新)。
- 准备目标语言(如
- 注意:动态切换主要影响后续获取的资源。部分系统界面元素可能不随应用即时改变。
5. 资源管理规范与最佳实践
- 目录命名:严格遵循
语言-文字-国家/地区格式(如zh-Hans-CN,en-US)。 - 回退机制:系统会自动查找最匹配的资源。例如,配置为
en-GB但未找到时,会回退到en或默认资源。 - 测试:在
module.json5中配置"supportLanguages"字段声明支持的语言,并使用设备或模拟器的语言设置进行充分测试。
此方案完全基于HarmonyOS Next(API 20)的现有能力,可系统化地实现应用的国际化与区域适配。

