深色模式
Flutter 国际化(Internationalization,i18n)支持指南
什么是国际化和本地化
- 国际化(Internationalization,i18n):指在应用程序的设计和开发过程中,使其可以轻松适应不同的语言和区域设置。
- 本地化(Localization,l10n):将应用程序调整为特定语言和文化环境的过程,包括翻译文本、调整日期和数字格式等。
Flutter 国际化的基本步骤
在 Flutter 中,实现国际化通常涉及以下步骤:
- 配置国际化支持:添加必要的依赖和配置。
- 设置支持的语言:指定应用支持的语言和区域。
- 创建本地化资源:为每个支持的语言创建翻译文件。
- 在代码中使用本地化资源:替换硬编码的字符串,使用本地化的文本。
- 处理文本方向性:支持从左到右(LTR)和从右到左(RTL)的语言。
- 检测和切换语言:根据用户的设备设置或应用内设置切换语言。
配置 Flutter 国际化支持
添加依赖包
Flutter 提供了 flutter_localizations 包来支持国际化,还需要使用 intl 包来处理消息和格式化日期、数字等。
在 pubspec.yaml 中添加以下依赖:
yaml
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: ^0.18.1 # 确保使用最新版本
然后运行:
flutter pub get
更新 pubspec.yaml
在 flutter 部分,确保添加了 uses-material-design: true,以支持 Material Design 风格的组件。
yaml
flutter:
uses-material-design: true
设置支持的语言
在 MaterialApp 或 CupertinoApp 中,设置 localizationsDelegates 和 supportedLocales。
dart
import 'package:flutter_localizations/flutter_localizations.dart';
MaterialApp(
// ...
localizationsDelegates: [
// 本地化的代理类
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
// 添加自定义的代理类
AppLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // 英语
const Locale('zh', ''), // 简体中文
const Locale('zh', 'HK'), // 繁体中文(香港)
// 添加更多语言
],
localeResolutionCallback: (locale, supportedLocales) {
// 检测和选择合适的语言
for (var supportedLocale in supportedLocales) {
if (supportedLocale.languageCode == locale?.languageCode &&
supportedLocale.countryCode == locale?.countryCode) {
return supportedLocale;
}
}
// 默认使用英语
return supportedLocales.first;
},
// ...
)
创建本地化资源
使用 .arb 文件
.arb(Application Resource Bundle)文件是一种简单的 JSON 格式,包含键值对的字符串。每种语言创建一个对应的 .arb 文件。
步骤:
1. 创建 lib/l10n 目录。
2. 创建默认语言的 ARB 文件,例如 app_en.arb:
json
{
"@@locale": "en",
"title": "Welcome",
"message": "Hello, {name}!"
}
3. 创建其他语言的 ARB 文件,例如 app_zh.arb:
{
"@@locale": "zh",
"title": "欢迎",
"message": "你好,{name}!"
}
生成本地化代码
Flutter 提供了 intl_utils 包,可以根据 ARB 文件自动生成 Dart 代码。
安装 intl_utils:
在 dev_dependencies 中添加:
yaml
dev_dependencies:
intl_utils: ^2.4.2
配置生成器
在 pubspec.yaml 中添加:
yaml
flutter_intl:
enabled: true
arb_dir: lib/l10n
output_dir: lib/generated
生成本地化代码
运行命令:
flutter pub run intl_utils:generate
这将在 lib/generated 目录下生成 intl_messages.arb 和 messages_all.dart 等文件。
在代码中使用本地化资源
创建一个 AppLocalizations 类来访问本地化的字符串。
dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class AppLocalizations {
static Future<AppLocalizations> load(Locale locale) {
final String name =
locale.countryCode == null ? locale.languageCode : locale.toString();
final String localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((_) {
Intl.defaultLocale = localeName;
return AppLocalizations();
});
}
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}
String get title {
return Intl.message('Welcome', name: 'title');
}
String message(String name) {
return Intl.message(
'Hello, $name!',
name: 'message',
args: [name],
);
}
}
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
const AppLocalizationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode);
@override
Future<AppLocalizations> load(Locale locale) =>
AppLocalizations.load(locale);
@override
bool shouldReload(AppLocalizationsDelegate old) => false;
}
在 MaterialApp 中添加:
dart
localizationsDelegates: [
// ...
const AppLocalizationsDelegate(),
],
在组件中使用:
dart
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
return Scaffold(
appBar: AppBar(
title: Text(loc.title),
),
body: Center(
child: Text(loc.message('Flutter')),
),
);
}
处理文本方向性(LTR/RTL)
有些语言是从右到左(RTL)的,例如阿拉伯语、希伯来语。Flutter 自动支持文本方向性,但需要在 MaterialApp 中添加 supportedLocales。
dart
supportedLocales: [
const Locale('en', ''), // LTR
const Locale('ar', ''), // RTL
],
在组件中,可以使用 Directionality:
dart
Directionality(
textDirection: TextDirection.rtl,
child: Text('مرحبا'),
)
检测和切换语言
检测当前语言
dart
Locale currentLocale = Localizations.localeOf(context);
手动切换语言
在 MaterialApp 中添加一个 locale 属性,控制应用的语言。
dart
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
static _MyAppState of(BuildContext context) =>
context.findAncestorStateOfType<_MyAppState>();
}
class _MyAppState extends State<MyApp> {
Locale _locale;
void setLocale(Locale locale) {
setState(() {
_locale = locale;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
// ...
locale: _locale,
// ...
);
}
}
在应用中提供切换语言的选项:
dart
FlatButton(
onPressed: () {
MyApp.of(context).setLocale(Locale('zh', ''));
},
child: Text('切换到中文'),
)
另外
有些第三方包可以简化国际化流程,例如:
easy_localization