Flutter for OpenHarmony 多语言国际化超简单实现指南
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
嗨喽嗨喽,亲爱的小伙伴们!👋 今天给大家带来一个超级实用的教程------如何在 Flutter for OpenHarmony 应用中实现多语言切换功能!想象一下,你的应用可以瞬间从中文切换到英文,是不是超级酷呢?让我们开始这段奇妙的国际化之旅吧!✨
🌟 为什么要做多语言支持?
在这个全球化的时代,我们的应用可不能只说"中文"这一种语言哦!支持多语言有很多好处呢:
- 🌍 走向世界:让你的应用走出国门,被更多小伙伴使用
- 💖 用户体验:用户看到自己熟悉的语言,心里暖暖的
- 📈 提升留存:数据显示,支持多语言的应用用户留存率更高哦
- 🎯 专业形象:国际化是专业应用的标配呢
🎨 整体效果预览
先给大家看看最终效果:
┌─────────────────────────┐
│ 🇨🇳 中文模式 │
│ 首页 | 消息 | 工作台 │
└─────────────────────────┘
↓ 切换
┌─────────────────────────┐
│ 🇺🇸 English Mode │
│ Home | Message | Work │
└─────────────────────────┘
是不是很棒?接下来就教大家一步步实现这个神奇的功能!
📦 第一步:准备必要的"魔法道具"
在开始之前,我们需要在 pubspec.yaml 中添加一些依赖包。这些就是我们实现国际化的"魔法道具"啦!
yaml
dependencies:
flutter:
sdk: flutter
# 国际化核心库
intl: ^0.19.0
# 本地存储,记住用户的语言选择
shared_preferences: ^2.2.3
# 状态管理,让语言切换更丝滑
provider: ^6.1.2
添加完成后,记得运行 flutter pub get 来安装这些依赖哦!
🗂️ 第二步:创建语言资源文件
语言资源文件就像是一个"翻译词典",存放着所有文本的翻译。我们使用 ARB 格式(Application Resource Bundle),这是 Flutter 官方推荐的格式呢!
中文词典 (app_zh.arb)
在 lib/l10n/ 目录下创建 app_zh.arb 文件:
json
{
"@@locale": "zh",
"appName": "Flutter OpenHarmony",
"home": "首页",
"message": "消息",
"work": "工作台",
"discover": "发现",
"profile": "我的",
"settings": "设置",
"languageSettings": "语言设置",
"chinese": "中文",
"english": "English",
"followSystem": "跟随系统",
"languageChanged": "语言已切换为 {language}",
"notificationSettings": "通知设置",
"about": "关于我们",
"logout": "退出登录",
"personalInfo": "个人信息",
"checkUpdate": "检查更新",
"sentryMonitorTest": "Sentry 监控测试",
"flutterDeveloper": "Flutter 开发者",
"flutterForOH": "Flutter for OpenHarmony"
}
英文词典 (app_en.arb)
同样目录下创建 app_en.arb 文件:
json
{
"@@locale": "en",
"appName": "Flutter OpenHarmony",
"home": "Home",
"message": "Message",
"work": "Work",
"discover": "Discover",
"profile": "Profile",
"settings": "Settings",
"languageSettings": "Language Settings",
"chinese": "中文",
"english": "English",
"followSystem": "Follow System",
"languageChanged": "Language changed to {language}",
"notificationSettings": "Notification Settings",
"about": "About",
"logout": "Logout",
"personalInfo": "Personal Information",
"checkUpdate": "Check Update",
"sentryMonitorTest": "Sentry Monitor Test",
"flutterDeveloper": "Flutter Developer",
"flutterForOH": "Flutter for OpenHarmony"
}
💡 小贴士:保持两个文件的键名完全一致,这样对比起来更清晰哦!
🔧 第三步:实现本地存储服务
我们需要一个"小本本"来记住用户选择的语言,这样即使应用关闭再打开,语言设置也不会丢失。这就是 LocaleStorageService 的作用啦!
创建文件 lib/services/locale_storage_service.dart:
dart
import 'package:shared_preferences/shared_preferences.dart';
/// 语言本地存储服务
/// 就像一个小本本,记住用户选择的语言
class LocaleStorageService {
static const String _localeKey = 'app_locale';
// 单例模式,全局只有一个实例
static LocaleStorageService? _instance;
static LocaleStorageService get instance =>
_instance ??= LocaleStorageService._internal();
LocaleStorageService._internal();
/// 获取保存的语言设置
/// 返回 'zh'、'en' 或 'system'
Future<String?> getSavedLocale() async {
try {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(_localeKey);
} catch (e) {
// 如果读取失败,就返回 null,使用默认语言
return null;
}
}
/// 保存语言设置
Future<bool> saveLocale(String localeCode) async {
try {
final prefs = await SharedPreferences.getInstance();
return prefs.setString(_localeKey, localeCode);
} catch (e) {
return false;
}
}
/// 清除保存的语言设置
Future<bool> clearSavedLocale() async {
try {
final prefs = await SharedPreferences.getInstance();
return prefs.remove(_localeKey);
} catch (e) {
return false;
}
}
}
🎭 第四步:创建国际化代理类
这个代理类就像一个"翻译官",根据当前语言提供对应的翻译文本。
创建文件 lib/l10n/app_localizations.dart:
dart
import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'app_localizations_zh.dart';
import 'app_localizations_en.dart';
/// 国际化基类
/// 所有翻译的"总指挥"
abstract class AppLocalizationsBase {
static AppLocalizationsBase? _current;
/// 获取当前语言实例
static AppLocalizationsBase get current {
if (_current == null) {
_current = AppLocalizationsEn(); // 默认英文
}
return _current!;
}
/// 设置语言
static void setLocale(Locale locale) {
switch (locale.languageCode) {
case 'zh':
_current = AppLocalizationsZh();
break;
case 'en':
default:
_current = AppLocalizationsEn();
break;
}
}
/// 本地化代理
static const LocalizationsDelegate<AppLocalizationsBase> delegate =
_AppLocalizationsDelegate();
/// 支持的语言列表
static List<Locale> get supportedLocales => const [
Locale('zh', 'CN'),
Locale('en', 'US'),
];
/// 从上下文获取国际化对象
static AppLocalizationsBase of(BuildContext context) {
return Localizations.of<AppLocalizationsBase>(
context,
AppLocalizationsBase
) ?? current;
}
// 翻译键定义(部分示例)
String get appName;
String get home;
String get message;
String get work;
String get discover;
String get profile;
String get settings;
String get languageSettings;
String get chinese;
String get english;
String get followSystem;
String languageChanged(String language);
String get notificationSettings;
String get about;
String get logout;
String get personalInfo;
String get checkUpdate;
String get sentryMonitorTest;
String get flutterDeveloper;
String get flutterForOH;
}
/// 本地化代理实现
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizationsBase> {
const _AppLocalizationsDelegate();
@override
bool isSupported(Locale locale) {
return ['zh', 'en'].contains(locale.languageCode);
}
@override
Future<AppLocalizationsBase> load(Locale locale) async {
AppLocalizationsBase localizations;
switch (locale.languageCode) {
case 'zh':
localizations = AppLocalizationsZh();
break;
case 'en':
default:
localizations = AppLocalizationsEn();
break;
}
AppLocalizationsBase._current = localizations;
Intl.defaultLocale = locale.languageCode;
return localizations;
}
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
/// 便捷访问类
/// 使用 F.tr.xxx 快速获取翻译
class F {
static AppLocalizationsBase get tr => AppLocalizationsBase.current;
static AppLocalizationsBase of(BuildContext context) {
return AppLocalizationsBase.of(context);
}
}
中文实现 (app_localizations_zh.dart)
dart
import 'app_localizations.dart';
/// 中文翻译实现
class AppLocalizationsZh extends AppLocalizationsBase {
@override
String get appName => 'Flutter OpenHarmony';
@override
String get home => '首页';
@override
String get message => '消息';
@override
String get work => '工作台';
@override
String get discover => '发现';
@override
String get profile => '我的';
@override
String get settings => '设置';
@override
String get languageSettings => '语言设置';
@override
String get chinese => '中文';
@override
String get english => 'English';
@override
String get followSystem => '跟随系统';
@override
String languageChanged(String language) => '语言已切换为 $language';
@override
String get notificationSettings => '通知设置';
@override
String get about => '关于我们';
@override
String get logout => '退出登录';
@override
String get personalInfo => '个人信息';
@override
String get checkUpdate => '检查更新';
@override
String get sentryMonitorTest => 'Sentry 监控测试';
@override
String get flutterDeveloper => 'Flutter 开发者';
@override
String get flutterForOH => 'Flutter for OpenHarmony';
}
英文实现 (app_localizations_en.dart)
dart
import 'app_localizations.dart';
/// 英文翻译实现
class AppLocalizationsEn extends AppLocalizationsBase {
@override
String get appName => 'Flutter OpenHarmony';
@override
String get home => 'Home';
@override
String get message => 'Message';
@override
String get work => 'Work';
@override
String get discover => 'Discover';
@override
String get profile => 'Profile';
@override
String get settings => 'Settings';
@override
String get languageSettings => 'Language Settings';
@override
String get chinese => '中文';
@override
String get english => 'English';
@override
String get followSystem => 'Follow System';
@override
String languageChanged(String language) => 'Language changed to $language';
@override
String get notificationSettings => 'Notification Settings';
@override
String get about => 'About';
@override
String get logout => 'Logout';
@override
String get personalInfo => 'Personal Information';
@override
String get checkUpdate => 'Check Update';
@override
String get sentryMonitorTest => 'Sentry Monitor Test';
@override
String get flutterDeveloper => 'Flutter Developer';
@override
String get flutterForOH => 'Flutter for OpenHarmony';
}
🎛️ 第五步:实现语言 Provider
Provider 就像一个"广播员",当语言改变时,它会通知所有页面更新显示。
创建文件 lib/providers/locale_provider.dart:
dart
import 'package:flutter/material.dart';
import '../services/locale_storage_service.dart';
/// 语言提供者
/// 管理语言状态,通知页面更新
class LocaleProvider extends ChangeNotifier {
final LocaleStorageService _storageService;
Locale _locale = const Locale('zh', 'CN');
Locale get locale => _locale;
// 支持的语言列表
static const List<Locale> supportedLocales = [
Locale('zh', 'CN'),
Locale('en', 'US'),
];
// 语言代码映射
static const Map<String, Locale> localeMap = {
'zh': Locale('zh', 'CN'),
'en': Locale('en', 'US'),
'system': null,
};
String _localeMode = 'system';
String get localeMode => _localeMode;
LocaleProvider({LocaleStorageService? storageService})
: _storageService = storageService ?? LocaleStorageService.instance;
/// 初始化,加载保存的语言设置
Future<void> init() async {
final savedLocale = await _storageService.getSavedLocale();
if (savedLocale != null) {
_localeMode = savedLocale;
if (savedLocale != 'system' && localeMap.containsKey(savedLocale)) {
_locale = localeMap[savedLocale]!;
}
}
notifyListeners();
}
/// 设置语言
Future<void> setLocale(String localeCode) async {
_localeMode = localeCode;
if (localeCode == 'system') {
await _storageService.saveLocale('system');
} else if (localeMap.containsKey(localeCode)) {
_locale = localeMap[localeCode]!;
await _storageService.saveLocale(localeCode);
}
// 通知所有监听者,UI 会立即刷新
notifyListeners();
}
}
🎨 第六步:创建语言设置页面
这是用户选择语言的界面,要做得漂亮一点哦!
创建文件 lib/pages/language_settings_page.dart:
dart
import 'package:flutter/material.dart';
import '../l10n/app_localizations.dart';
import '../providers/locale_provider.dart';
/// 语言设置页面
class LanguageSettingsPage extends StatelessWidget {
const LanguageSettingsPage({super.key});
@override
Widget build(BuildContext context) {
final localeProvider = LocaleInheritedWidget.of(context)!.localeProvider;
final l10n = AppLocalizations.of(context);
return Scaffold(
appBar: AppBar(
title: Text(l10n.languageSettings),
),
body: ListView(
children: [
_buildLanguageOption(
localeProvider: localeProvider,
l10n: l10n,
localeCode: 'system',
title: l10n.followSystem,
icon: Icons.settings_suggest,
),
const Divider(height: 1),
_buildLanguageOption(
localeProvider: localeProvider,
l10n: l10n,
localeCode: 'zh',
title: l10n.chinese,
subtitle: '简体中文',
icon: Icons.language,
),
const Divider(height: 1),
_buildLanguageOption(
localeProvider: localeProvider,
l10n: l10n,
localeCode: 'en',
title: l10n.english,
subtitle: 'English',
icon: Icons.language,
),
],
),
);
}
Widget _buildLanguageOption({
required LocaleProvider localeProvider,
required AppLocalizations l10n,
required String localeCode,
required String title,
String subtitle = '',
required IconData icon,
}) {
final isSelected = localeProvider.localeMode == localeCode;
return ListTile(
leading: Icon(
icon,
color: isSelected ? Theme.of(context).primaryColor : Colors.grey,
),
title: Text(
title,
style: TextStyle(
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
color: isSelected ? Theme.of(context).primaryColor : null,
),
),
subtitle: subtitle.isNotEmpty ? Text(subtitle) : null,
trailing: isSelected
? Icon(Icons.check_circle, color: Theme.of(context).primaryColor)
: const Icon(Icons.radio_button_unchecked, color: Colors.grey),
onTap: () async {
await localeProvider.setLocale(localeCode);
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(l10n.languageChanged(title)),
duration: const Duration(seconds: 2),
),
);
}
},
);
}
}
🚀 第七步:配置应用入口
最后一步,在 main.dart 中配置国际化支持:
dart
import 'package:flutter/material.dart';
import 'l10n/app_localizations.dart';
import 'providers/locale_provider.dart';
import 'services/locale_storage_service.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化本地存储服务
final storageService = LocaleStorageService.instance;
// 初始化语言 Provider
final localeProvider = LocaleProvider(storageService: storageService);
await localeProvider.init();
runApp(MyApp(localeProvider: localeProvider));
}
class MyApp extends StatefulWidget {
final LocaleProvider localeProvider;
const MyApp({super.key, required this.localeProvider});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: widget.localeProvider,
builder: (context, child) {
return MaterialApp(
title: 'Flutter OpenHarmony',
locale: widget.localeProvider.locale,
supportedLocales: AppLocalizations.supportedLocales,
localizationsDelegates: const [
AppLocalizations.delegate,
],
home: const HomePage(),
);
},
);
}
}
🎯 第八步:在页面中使用翻译
现在可以在任何页面中使用国际化文本啦!
dart
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);
return Scaffold(
appBar: AppBar(
title: Text(l10n.home),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
l10n.appName,
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/settings');
},
child: Text(l10n.settings),
),
],
),
),
);
}
}
✨ 运行效果

完成以上步骤后,你的应用就可以自由切换语言啦!
使用步骤:
- 打开应用,进入"我的"页面
- 点击"设置"
- 选择"语言设置"
- 点击想要的语言(中文/English/跟随系统)
- 瞬间切换,无需重启应用!
💡 小贴士
- 添加新语言超简单:只需创建新的 ARB 文件和实现类
- 翻译要准确:建议找母语者帮忙审核翻译质量
- 测试很重要:在真机上测试每种语言的显示效果
- 文本长度:不同语言文本长度不同,布局要留足空间
🎉 总结
恭喜你又学会了一个新技能!🎊 通过这篇教程,我们实现了:
- ✅ 使用 ARB 文件管理多语言翻译
- ✅ 利用 SharedPreferences 持久化语言设置
- ✅ 通过 Provider 实现实时语言切换
- ✅ 完整的语言设置页面
现在你的应用已经具备国际化能力啦,可以面向全球用户了!是不是很有成就感呢?💪