【maaath】Flutter for OpenHarmony 国际化集成指南:实现中英文动态切换
在移动应用开发中,国际化(Internationalization,简称 i18n)是一项必不可少的功能。对于使用 Flutter for OpenHarmony 进行跨平台开发的开发者而言,如何优雅地实现多语言切换是一个值得深入探讨的话题。本文将以实际项目为例,详细介绍如何在开源鸿蒙跨平台工程中集成国际化能力,实现中英文动态切换,并在模拟器上完成验证。
Flutter for OpenHarmony 国际化集成指南:实现中英文动态切换
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
作者:maaath
一、背景介绍
在移动应用开发中,国际化(Internationalization,简称 i18n)是一项必不可少的功能。对于使用 Flutter for OpenHarmony 进行跨平台开发的开发者而言,如何优雅地实现多语言切换是一个值得深入探讨的话题。本文将以实际项目为例,详细介绍如何在开源鸿蒙跨平台工程中集成国际化能力,实现中英文动态切换,并在模拟器上完成验证。
与纯 Flutter 应用不同,Flutter for OpenHarmony 项目采用混合架构:原生鸿蒙 ArkTS 层负责应用入口和平台能力,Flutter 层负责 UI 渲染。因此,国际化方案需要同时考虑鸿蒙原生层和 Flutter 层的协同工作。本文将重点讲解鸿蒙原生层的国际化实现,为 Flutter 层提供语言切换的基础能力。
二、国际化架构设计
2.1 整体思路
为了实现灵活的语言切换功能,我们设计了以下核心模块:
| 模块 | 职责 |
|---|---|
| I18nManager | 语言管理器,负责语言状态管理、持久化存储、变更通知 |
| StringManager | 字符串资源管理器,提供多语言字符串的统一访问接口 |
| 资源文件 | 按语言目录组织的 JSON 字符串资源 |
2.2 目录结构
entry/src/main/
├── ets/
│ ├── entryability/
│ │ └── EntryAbility.ets # 应用入口,初始化国际化
│ ├── pages/
│ │ └── Index.ets # 主页面,展示国际化效果
│ └── utils/
│ ├── I18nManager.ets # 国际化管理器
│ └── StringManager.ets # 字符串管理器
└── resources/
├── base/element/string.json # 默认字符串资源
├── en_US/element/string.json # 英文资源
└── zh_CN/element/string.json # 中文资源
三、核心代码实现
3.1 国际化管理器(I18nManager)
I18nManager 是整个国际化方案的核心,采用单例模式设计,提供语言切换、持久化存储和监听器机制。
import preferences from '@ohos.data.preferences';
import { common } from '@kit.AbilityKit';
const PREFERENCES_NAME = 'i18n_preferences';
const LANGUAGE_KEY = 'app_language';
export class I18nManager {
private static instance: I18nManager;
private preferences: preferences.Preferences | null = null;
private currentLanguage: string = 'zh-CN';
private listeners: Array<(language: string) => void> = [];
private constructor() {}
static getInstance(): I18nManager {
if (!I18nManager.instance) {
I18nManager.instance = new I18nManager();
}
return I18nManager.instance;
}
async init(context: common.UIAbilityContext): Promise<void> {
try {
this.preferences = await preferences.getPreferences(context, PREFERENCES_NAME);
const language: string = await this.preferences.get(LANGUAGE_KEY, 'zh-CN') as string;
this.currentLanguage = language;
} catch (error) {
console.error('I18nManager init error:', JSON.stringify(error));
this.currentLanguage = 'zh-CN';
}
}
getLanguage(): string {
return this.currentLanguage;
}
isEnglish(): boolean {
return this.currentLanguage === 'en-US';
}
async setLanguage(language: string): Promise<void> {
if (this.currentLanguage === language) {
return;
}
this.currentLanguage = language;
if (this.preferences) {
try {
await this.preferences.put(LANGUAGE_KEY, language);
await this.preferences.flush();
} catch (error) {
console.error('I18nManager setLanguage error:', JSON.stringify(error));
}
}
this.notifyListeners();
}
async switchLanguage(): Promise<void> {
const newLanguage = this.currentLanguage === 'zh-CN' ? 'en-US' : 'zh-CN';
await this.setLanguage(newLanguage);
}
addLanguageChangeListener(callback: (language: string) => void): void {
this.listeners.push(callback);
}
removeLanguageChangeListener(callback: (language: string) => void): void {
const index = this.listeners.indexOf(callback);
if (index > -1) {
this.listeners.splice(index, 1);
}
}
private notifyListeners(): void {
this.listeners.forEach(callback => {
callback(this.currentLanguage);
});
}
}
export const i18nManager = I18nManager.getInstance();
代码要点解析:
- 单例模式:确保全局只有一个语言管理实例,避免状态不一致
- 持久化存储:使用
@ohos.data.preferences保存用户选择的语言,应用重启后自动恢复 - 监听器机制:采用观察者模式,当语言切换时通知所有注册的监听器,实现 UI 自动刷新
- 错误处理:所有异步操作都包含 try-catch,确保应用稳定性
3.2 字符串管理器(StringManager)
StringManager 封装了多语言字符串资源,提供统一的访问接口。
import { i18nManager } from './I18nManager';
export class StringManager {
private static instance: StringManager;
private stringResources: Record<string, Record<string, string>> = {
'zh-CN': {
'app_name': '开源鸿蒙',
'welcome': '欢迎使用开源鸿蒙',
'settings': '设置',
'language': '语言',
'switch_language': '切换语言',
'current_language': '当前语言',
'chinese': '中文',
'english': '英文',
'description': '这是一个支持中英文切换的开源鸿蒙应用',
'flutter_view': 'Flutter 页面',
'about': '关于',
'version': '版本'
},
'en-US': {
'app_name': 'OpenHarmony',
'welcome': 'Welcome to OpenHarmony',
'settings': 'Settings',
'language': 'Language',
'switch_language': 'Switch Language',
'current_language': 'Current Language',
'chinese': 'Chinese',
'english': 'English',
'description': 'This is an OpenHarmony app with Chinese/English switching support',
'flutter_view': 'Flutter Page',
'about': 'About',
'version': 'Version'
}
};
private constructor() {}
static getInstance(): StringManager {
if (!StringManager.instance) {
StringManager.instance = new StringManager();
}
return StringManager.instance;
}
getString(key: string): string {
const currentLang = i18nManager.getLanguage();
const langStrings = this.stringResources[currentLang] || this.stringResources['zh-CN'];
return langStrings[key] || key;
}
getStringByLang(key: string, lang: string): string {
const langStrings = this.stringResources[lang] || this.stringResources['zh-CN'];
return langStrings[key] || key;
}
getAllLanguages(): string[] {
return Object.keys(this.stringResources);
}
}
export const stringManager = StringManager.getInstance();
3.3 资源文件配置
鸿蒙系统支持基于目录的语言资源管理,在 resources 目录下创建不同语言的子目录:
中文资源(zh_CN/element/string.json):
{
"string": [
{
"name": "module_desc",
"value": "模块描述"
},
{
"name": "app_name",
"value": "开源鸿蒙示例"
},
{
"name": "welcome",
"value": "欢迎"
},
{
"name": "settings",
"value": "设置"
},
{
"name": "language",
"value": "语言"
},
{
"name": "switch_language",
"value": "切换语言"
},
{
"name": "current_language",
"value": "当前语言:中文"
},
{
"name": "description",
"value": "支持国际化的开源鸿蒙应用"
}
]
}
英文资源(en_US/element/string.json):
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "app_name",
"value": "OpenHarmony Demo"
},
{
"name": "welcome",
"value": "Welcome"
},
{
"name": "settings",
"value": "Settings"
},
{
"name": "language",
"value": "Language"
},
{
"name": "switch_language",
"value": "Switch Language"
},
{
"name": "current_language",
"value": "Current: English"
},
{
"name": "description",
"value": "OpenHarmony App with i18n Support"
}
]
}
3.4 应用入口初始化
在 EntryAbility.ets 中初始化国际化管理器:
import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos';
import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant';
import { i18nManager } from '../utils/I18nManager';
import { Want, AbilityConstant } from '@kit.AbilityKit';
export default class EntryAbility extends FlutterAbility {
async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
super.onCreate(want, launchParam);
await i18nManager.init(this.context);
}
configureFlutterEngine(flutterEngine: FlutterEngine): void {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
}
}
3.5 页面集成
在主页面中集成国际化功能,实现语言切换按钮和动态文本显示:
import common from '@ohos.app.ability.common';
import { FlutterPage } from '@ohos/flutter_ohos'
import { i18nManager } from '../utils/I18nManager';
import { stringManager } from '../utils/StringManager';
let storage = LocalStorage.getShared()
const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS'
@Entry(storage)
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext
@LocalStorageLink('viewId') viewId: string = "";
@State currentLanguage: string = 'zh-CN'
@State displayText: string = ''
aboutToAppear() {
this.currentLanguage = i18nManager.getLanguage();
this.updateDisplayText();
i18nManager.addLanguageChangeListener(this.onLanguageChange.bind(this))
}
aboutToDisappear() {
i18nManager.removeLanguageChangeListener(this.onLanguageChange.bind(this))
}
onLanguageChange(language: string) {
this.currentLanguage = language
this.updateDisplayText()
}
updateDisplayText() {
this.displayText = stringManager.getString('welcome') + '\n' +
stringManager.getString('description')
}
async switchLanguage() {
await i18nManager.switchLanguage()
}
build() {
Column() {
Row() {
Text(stringManager.getString('app_name'))
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, left: 20 })
Blank()
Button(stringManager.getString('switch_language'))
.margin({ top: 20, right: 20 })
.onClick(() => {
this.switchLanguage()
})
}
.width('100%')
Row() {
Text(stringManager.getString('current_language') + ': ')
.fontSize(16)
Text(this.currentLanguage === 'zh-CN' ?
stringManager.getString('chinese') :
stringManager.getString('english'))
.fontSize(16)
.fontColor('#007DFF')
}
.margin({ top: 10 })
Column() {
Text(this.displayText)
.fontSize(18)
.textAlign(TextAlign.Center)
.margin({ top: 20 })
}
.margin({ top: 20 })
Divider().margin({ top: 20 })
Text(stringManager.getString('flutter_view'))
.fontSize(16)
.margin({ top: 10 })
Column() {
FlutterPage({ viewId: this.viewId })
.width('100%')
.layoutWeight(1)
}
}
.width('100%')
.height('100%')
}
onBackPress(): boolean {
this.context.eventHub.emit(EVENT_BACK_PRESS)
return true
}
}
页面实现要点:
- 状态变量:使用
@State装饰器声明响应式变量,语言切换时自动触发 UI 刷新 - 生命周期管理:在
aboutToAppear注册监听器,在aboutToDisappear移除监听器,避免内存泄漏 - 动态文本:所有显示文本都通过
stringManager.getString()获取,确保语言切换后文本同步更新
四、运行验证
4.1 构建与部署
使用 hvigor 构建工具编译项目:
hvigorw assembleHap --mode module -p product=default -p module=entry@default
构建成功后,通过 hdc 工具安装到模拟器:
hdc install -r entry/build/default/outputs/default/entry-default-unsigned.hap
启动应用:
hdc shell aa start -a EntryAbility -b com.example.oh_demo8
4.2 运行效果
应用启动后,界面显示中文内容。点击右上角的"切换语言"按钮,界面即时切换为英文显示。再次点击,切换回中文。
运行日志验证:
SetLocale language tag: zh-CN, select language: zh-CN
SetLanguage: zh, colorMode: light, deviceAccess: 1
日志显示语言设置成功,国际化功能正常运行。
4.3 运行截图

图1:中文界面展示

图2:英文界面展示
五、最佳实践与注意事项
5.1 语言代码规范
鸿蒙系统采用标准的语言区域代码格式:
- 中文(简体):
zh-CN或zh-Hans - 英文:
en-US或en
建议在项目中统一使用 zh-CN 和 en-US 格式,保持一致性。
5.2 持久化存储时机
语言选择应在用户主动切换时立即持久化,而非应用退出时保存。这样可以确保:
- 应用异常退出时不会丢失用户设置
- 多进程场景下语言状态一致
5.3 监听器内存管理
务必在组件销毁时移除监听器,否则会导致:
- 内存泄漏
- 已销毁组件的回调被触发,引发异常
5.4 与 Flutter 层的通信
如需将语言切换同步到 Flutter 层,可以通过 MethodChannel 或 EventChannel 实现:
// Flutter 端
static const MethodChannel _channel = MethodChannel('i18n_channel');
Future<void> switchLanguage() async {
await _channel.invokeMethod('switchLanguage');
}
// 鸿蒙端
methodChannel.setMethodCallHandler((call: MethodCall) => {
if (call.method === 'switchLanguage') {
i18nManager.switchLanguage();
}
return null;
});
六、总结
本文详细介绍了在 Flutter for OpenHarmony 跨平台工程中集成国际化能力的完整方案。通过设计 I18nManager 和 StringManager 两个核心模块,实现了语言状态的统一管理、持久化存储和动态切换。该方案具有以下优势:
- 架构清晰:职责分离,易于维护和扩展
- 响应式更新:基于监听器机制,语言切换后 UI 自动刷新
- 持久化支持:用户语言偏好自动保存,应用重启后恢复
- 扩展性强:支持轻松添加更多语言
希望本文能为开源鸿蒙跨平台开发者提供有价值的参考,助力构建更加国际化的应用。
感谢各位阅读!
更多推荐



所有评论(0)