第11章:Flutter 国际化与多语言支持
随着应用的全球化,国际化(i18n) 是不可或缺的一部分。Flutter 提供了强大的多语言支持机制,配合工具可以快速实现中英文甚至多国语言切换。
一、使用 flutter_localizations
国际化支持包
Flutter 官方提供了内置的国际化支持,依赖于:
flutter_localizations
:Flutter 官方语言包intl
:处理时间、数字、本地格式化
二、步骤一:添加依赖
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: ^0.18.0
三、步骤二:配置 MaterialApp
MaterialApp(
locale: Locale('zh'), // 设置默认语言(可留空自动根据系统)
supportedLocales: const [
Locale('en'), // 英文
Locale('zh'), // 中文
],
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
AppLocalizations.delegate, // 自定义多语言资源类
],
home: HomePage(),
)
四、步骤三:生成多语言资源
推荐方式:使用 Flutter 官方的 flutter gen-l10n
工具
1. 配置 l10n.yaml
文件(项目根目录)
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
2. 创建语言资源文件
📄 lib/l10n/app_en.arb
{
"@@locale": "en",
"hello": "Hello",
"welcome": "Welcome to Flutter!"
}
📄 lib/l10n/app_zh.arb
{
"@@locale": "zh",
"hello": "你好",
"welcome": "欢迎使用 Flutter!"
}
3. 自动生成本地化代码
运行命令:
flutter gen-l10n
会自动生成 AppLocalizations
类,之后即可在代码中使用。
五、在页面中使用多语言字符串
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@override
Widget build(BuildContext context) {
final local = AppLocalizations.of(context)!;
return Text(local.hello); // 自动根据当前语言显示“Hello”或“你好”
}
六、动态切换语言(可持久化)
使用 Provider 或状态管理持有当前语言:
class LocaleProvider with ChangeNotifier {
Locale _locale = const Locale('en');
Locale get locale => _locale;
void setLocale(Locale locale) {
_locale = locale;
notifyListeners();
}
}
在 MaterialApp
中使用:
locale: Provider.of<LocaleProvider>(context).locale,
切换语言按钮示例:
ElevatedButton(
onPressed: () {
context.read<LocaleProvider>().setLocale(Locale('zh'));
},
child: Text('切换到中文'),
)
七、常见问题解析
❗ 问题 1:AppLocalizations 无法识别?
- 确认已执行
flutter gen-l10n
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
是否引入?AppLocalizations.delegate
是否添加到localizationsDelegates
?
❗ 问题 2:中文不显示或乱码?
- 检查中文
arb
文件格式(必须为 UTF-8) - 确认中文语言已加入
supportedLocales
- Android 系统语言是否设置为中文?
❗ 问题 3:切换语言后界面不刷新?
- 必须使用
setState()
或状态管理触发locale
更新 - 多语言要放在 Widget rebuild 中使用,不要缓存字符串