鸿蒙 ArkTS 国际化:多语言支持与资源管理



一、引言
随着应用的全球化发展,国际化(i18n)成为应用开发的重要组成部分。一个优秀的国际化方案能让应用支持多种语言、适应不同地区的文化习惯、正确显示日期时间和货币格式。HarmonyOS 提供了完善的国际化能力,包括资源文件管理、i18n 模块和 Intl 模块。
本文将以一个多彩渐变风格的国际演示页面为主线,深入讲解 HarmonyOS 国际化的核心概念和实战技巧,帮助读者掌握多语言开发的技能。
二、国际化基础概念
2.1 什么是国际化
国际化(Internationalization,缩写 i18n)是指设计和开发应用时,使其能够适应不同语言和地区的技术过程。核心目标:
- 多语言支持:界面文字可以切换多种语言。
- 地区适应:日期、时间、货币、数字格式随地区变化。
- 资源分离:文本资源与代码分离,便于翻译和维护。
2.2 语言与地区
- 语言:如中文、英文、日文。
- 地区:如中国大陆(CN)、美国(US)、日本(JP)。
- Locale:语言和地区的组合,如
zh_CN(简体中文-中国)、en_US(英语-美国)、ja_JP(日语-日本)。
三、资源文件管理
3.1 资源目录结构
HarmonyOS 通过资源目录实现多语言支持:
entry/src/main/resources/
├── base/ # 默认资源(兜底)
│ ├── element/ # 字符串、颜色等
│ └── media/ # 图片等
├── zh_CN/ # 简体中文资源
│ └── element/
│ └── string.json
├── en_US/ # 英语资源
│ └── element/
│ └── string.json
└── ja_JP/ # 日语资源
└── element/
└── string.json
3.2 定义字符串资源
在 base/element/string.json 中定义默认字符串:
{
"string": [
{
"name": "app_title",
"value": "My Application"
},
{
"name": "app_hello",
"value": "Hello, World"
}
]
}
在 zh_CN/element/string.json 中定义中文翻译:
{
"string": [
{
"name": "app_title",
"value": "我的应用"
},
{
"name": "app_hello",
"value": "你好,世界"
}
]
}
3.3 在代码中使用资源
// 使用字符串资源
Text($r('app.string.app_title'))
// 带参数
Text($r('app.string.welcome', '张三'))
代码说明:
$r('app.string.xxx')引用字符串资源。- 系统会根据当前语言自动选择对应语言目录中的资源。
- 支持带参数格式化。
四、i18n 模块
4.1 系统语言管理
import { i18n } from '@kit.LocalizationKit';
// 获取系统语言
const lang = i18n.System.getSystemLanguage();
console.info(`系统语言: ${lang}`);
// 设置系统语言
i18n.System.setSystemLanguage('zh_CN');
4.2 获取系统区域
// 获取系统区域
const region = i18n.System.getSystemRegion();
console.info(`系统区域: ${region}`);
// 获取系统时区
const timezone = i18n.System.getSystemTimezone();
console.info(`系统时区: ${timezone}`);
4.3 判断语言方向
// 判断是否 RTL(从右到左)语言
const isRTL = i18n.isRTL('ar');
console.info(`阿拉伯语是否 RTL: ${isRTL}`);
五、Intl 模块
Intl 模块用于国际化格式化,包括日期、时间、数字、货币等。
5.1 日期格式化
import { Intl } from '@kit.LocalizationKit';
// 创建日期格式化器
const dateFmt = new Intl.DateTimeFormat('zh-CN', {
dateStyle: 'full',
timeStyle: 'medium'
});
// 格式化日期
const dateStr = dateFmt.format(new Date());
console.info(`格式化日期: ${dateStr}`);
5.2 数字格式化
// 创建数字格式化器
const numFmt = new Intl.NumberFormat('zh-CN', {
style: 'decimal',
minimumFractionDigits: 2
});
// 格式化数字
const numStr = numFmt.format(1234.567);
console.info(`格式化数字: ${numStr}`); // 1,234.57
5.3 货币格式化
// 创建货币格式化器
const currencyFmt = new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
});
// 格式化货币
const moneyStr = currencyFmt.format(99.9);
console.info(`格式化货币: ${moneyStr}`); // ¥99.90
六、实战代码:多语言演示页面
下面我们实现一个多彩渐变风格的国际演示页面,包含语言切换、多语言对照表。
6.1 定义数据结构
interface I18nRow {
key: string;
zh: string;
en: string;
ja: string;
}
代码说明:
I18nRow 接口描述多语言对照表中的一行数据,包含资源键和三种语言的翻译。
6.2 组件状态定义
@Entry
@Component
struct I18nPage {
@State currentLang: string = 'zh_CN';
@State rows: I18nRow[] = [
{ key: 'app.title', zh: 'HarmonyOS 应用', en: 'HarmonyOS App', ja: 'ハーモニーOSアプリ' },
{ key: 'app.hello', zh: '你好,世界', en: 'Hello, World', ja: 'こんにちは、世界' },
{ key: 'app.welcome', zh: '欢迎使用', en: 'Welcome', ja: 'ようこそ' },
{ key: 'app.confirm', zh: '确定', en: 'OK', ja: '決定' },
{ key: 'app.cancel', zh: '取消', en: 'Cancel', ja: 'キャンセル' }
];
@State tabIndex: number = 0;
代码说明:
@State currentLang:当前语言。@State rows:多语言对照表数据,每种语言三列。@State tabIndex:Tabs 分页索引。
6.3 获取当前语言文本
getText(row: I18nRow): string {
if (this.currentLang === 'zh_CN') {
return row.zh;
} else if (this.currentLang === 'en_US') {
return row.en;
}
return row.ja;
}
代码说明:
getText 根据当前语言返回对应的文本:
zh_CN返回中文。en_US返回英文。- 其他(ja_JP)返回日文。
6.4 切换语言
switchLang(lang: string): void {
this.currentLang = lang;
try {
i18n.System.setSystemLanguage(lang);
} catch (e) {
// 模拟环境无法切换系统语言,仅切换界面文案
}
promptAction.showToast({ message: `已切换语言: ${lang}` });
}
代码说明:
switchLang 切换语言:
- 更新状态:
this.currentLang = lang更新界面语言,触发 UI 刷新。 - 尝试切换系统语言:调用
i18n.System.setSystemLanguage,在真机上会改变系统语言。模拟环境中可能失败,用try...catch捕获。 - 提示反馈:Toast 提示切换结果。
6.5 构建 UI
build() {
Column() {
// 顶部多彩渐变标题
Column() {
Text('I18N')
.fontSize(12)
.fontColor('#FFFFFFCC')
.letterSpacing(8)
Text('国际化与多语言')
.fontSize(26)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.margin({ top: 6 })
Text('i18n · 资源文件 · 多语言切换')
.fontSize(12)
.fontColor('#FFFFFFCC')
.margin({ top: 6 })
}
.width('100%')
.padding({ top: 48, bottom: 28 })
.linearGradient({
angle: 120,
colors: [['#EE5A24', 0], ['#FFA502', 0.4], ['#2ED573', 0.7], ['#18DCFF', 1]]
})
// 语言切换按钮组
Row({ space: 10 }) {
Button('中文')
.height(40)
.layoutWeight(1)
.fontSize(13)
.fontColor(this.currentLang === 'zh_CN' ? Color.White : '#EE5A24')
.backgroundColor(this.currentLang === 'zh_CN' ? '#EE5A24' : '#FFFFFF')
.borderRadius(20)
.border({ width: 1, color: '#EE5A24' })
.onClick(() => { this.switchLang('zh_CN'); })
Button('English')
.height(40)
.layoutWeight(1)
.fontSize(13)
.fontColor(this.currentLang === 'en_US' ? Color.White : '#18DCFF')
.backgroundColor(this.currentLang === 'en_US' ? '#18DCFF' : '#FFFFFF')
.borderRadius(20)
.border({ width: 1, color: '#18DCFF' })
.onClick(() => { this.switchLang('en_US'); })
Button('日本語')
.height(40)
.layoutWeight(1)
.fontSize(13)
.fontColor(this.currentLang === 'ja_JP' ? Color.White : '#FFA502')
.backgroundColor(this.currentLang === 'ja_JP' ? '#FFA502' : '#FFFFFF')
.borderRadius(20)
.border({ width: 1, color: '#FFA502' })
.onClick(() => { this.switchLang('ja_JP'); })
}
.width('100%')
.padding(16)
代码说明:
语言切换按钮组:
- 三个按钮分别对应中文、英文、日文。
- 每个按钮使用不同的主题色:中文=橙色(#EE5A24)、英文=青色(#18DCFF)、日文=橙色(#FFA502)。
- 选中按钮使用实心主题色背景、白色文字;未选中使用白色背景、彩色文字和描边。
- 通过条件判断
this.currentLang === 'zh_CN'控制选中态样式。
// Tabs 分页展示
Tabs({ barPosition: BarPosition.Start, index: this.tabIndex }) {
TabContent() {
Column({ space: 10 }) {
ForEach(this.rows, (row: I18nRow) => {
Row({ space: 12 }) {
Text(row.key)
.fontSize(12)
.fontColor('#999999')
.fontFamily('monospace')
.width(90)
Text(this.getText(row))
.fontSize(16)
.fontWeight(FontWeight.Medium)
.fontColor('#2F3542')
.layoutWeight(1)
}
.width('100%')
.padding(14)
.backgroundColor(Color.White)
.borderRadius(12)
.shadow({ radius: 4, color: '#11000000', offsetY: 2 })
})
}
.width('100%')
.padding(16)
}
.tabBar('当前语言')
}
.width('100%')
.layoutWeight(1)
代码说明:
Tabs 分页展示当前语言下的文本:
- 每行显示资源键(等宽灰色字体)和当前语言的翻译文本。
this.getText(row)根据当前语言动态返回对应文本。- 切换语言时,由于
currentLang是@State,UI 自动刷新,所有文本立即更新。
// 多语言对照表
Column() {
Text('多语言对照表')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.fontColor('#EE5A24')
.alignSelf(ItemAlign.Start)
.margin({ bottom: 8 })
Row() {
Text('键').layoutWeight(1).fontSize(11).fontColor('#EE5A24')
Text('中文').layoutWeight(1).fontSize(11).fontColor('#EE5A24')
Text('English').layoutWeight(1).fontSize(11).fontColor('#18DCFF')
Text('日本語').layoutWeight(1).fontSize(11).fontColor('#FFA502')
}
.width('100%')
.padding(8)
.backgroundColor('#FFF0E6')
Scroll() {
ForEach(this.rows, (row: I18nRow) => {
Row() {
Text(row.key).layoutWeight(1).fontSize(10).fontColor('#999999').fontFamily('monospace')
Text(row.zh).layoutWeight(1).fontSize(11).fontColor('#2F3542')
Text(row.en).layoutWeight(1).fontSize(11).fontColor('#2F3542')
Text(row.ja).layoutWeight(1).fontSize(11).fontColor('#2F3542')
}
.width('100%')
.padding(8)
.border({ width: { bottom: 1 }, color: '#FFF0E6' })
})
}
.layoutWeight(1)
}
.width('100%')
.height(220)
.padding(12)
.backgroundColor('#FFFBF7')
.borderRadius(14)
.border({ width: 1, color: '#FFE0C8' })
Button('返回首页')
.width('100%')
.height(46)
.fontSize(15)
.fontColor(Color.White)
.backgroundColor('#EE5A24')
.borderRadius(23)
.onClick(() => { router.back(); })
}
.width('100%')
.height('100%')
.backgroundColor('#FFF8F0')
}
代码说明:
多语言对照表是四列表格:
- 表头:键、中文、English、日本語,每种语言使用对应主题色。
- 数据行:每行展示同一资源键在三种语言下的翻译,方便对比。
- 表格支持滚动查看。
七、国际化最佳实践
7.1 资源分离
所有界面文字都应放在资源文件中,避免硬编码在代码里。这样翻译时只需修改资源文件,无需改动代码。
7.2 语言目录规划
为每个支持的语言创建独立目录,base 目录作为兜底默认值:
resources/
├── base/
├── zh_CN/
├── en_US/
└── ja_JP/
7.3 占位符使用
使用带参数的字符串资源,避免字符串拼接:
{
"string": [
{
"name": "welcome_user",
"value": "欢迎,%s!"
}
]
}
Text($r('app.string.welcome_user', '张三'))
7.4 日期时间本地化
使用 Intl 模块格式化日期、时间、数字、货币,确保符合当地习惯。
7.5 文本长度适配
不同语言的文本长度差异很大(如德语较长),UI 设计时需考虑文本溢出,使用 maxLines 和 textOverflow 处理。
八、常见问题
8.1 切换语言不生效
原因:只修改了界面状态,没有更新系统语言,或资源文件缺失。
解决:调用 i18n.System.setSystemLanguage,确保对应语言目录存在。
8.2 中文乱码
原因:文件编码问题。
解决:确保资源文件使用 UTF-8 编码。
8.3 文本溢出
原因:不同语言文本长度差异大。
解决:使用 maxLines、textOverflow、自适应布局。
九、总结
本文深入讲解了 HarmonyOS 国际化技术,通过一个多彩渐变风格的国际演示页面实战演示了多语言切换、资源管理和文本本地化等核心能力。
核心要点回顾:
- 国际化让应用支持多种语言和地区。
- 资源目录结构:base 兜底 + 各语言目录。
$r()引用字符串资源,系统自动选择语言。i18n模块管理系统语言、区域、时区。Intl模块格式化日期、时间、数字、货币。- 资源分离、占位符、文本适配是最佳实践。
国际化是应用走向全球市场的关键能力,掌握它能构建真正国际化的应用。至此,我们的 16 篇技术专题博客已全部完成,覆盖了 HarmonyOS 开发的各个核心方向。
更多推荐




所有评论(0)