Flutter - 国际化
Flutter - 国际化 (i18n)
Section titled “Flutter - 国际化 (i18n)”国际化(Internationalization)(通常缩写为 i18n)是设计和开发你的应用程序的过程,使其无需进行工程更改即可轻松适应各种语言和地区。本地化(Localization)(l10n)是后续过程,通过添加特定于语言环境的组件和翻译文本,将国际化的应用程序适应特定区域或语言。
Flutter 为 i18n 和 l10n 提供了出色的支持,使你的应用能够触及全球用户。
Locale: 代表用户首选语言和可选地区(国家代码)的对象。示例:Locale('en')(英语),Locale('en', 'US')(美式英语),Locale('es', 'AR')(阿根廷西班牙语)。- 本地化消息(Localized Messages): 特定于每种支持的语言环境的文本字符串和其他语言环境敏感数据(如日期/时间格式、数字格式、货币)。
LocalizationsWidget: 一个 widget,提供在 widget 树中访问本地化值的功能。位于其下方的 widgets 可以获取当前的Locale和相应的资源。LocalizationsDelegate: 一个工厂,负责创建特定Localizations类的实例(例如,你的应用消息、Material/Cupertino widget 翻译)。它决定支持哪些语言环境并加载相应的资源。
官方 Flutter 国际化方法
Section titled “官方 Flutter 国际化方法”推荐的方法是使用 flutter_localizations 包(用于内置 widget 的翻译)和 intl 包(用于处理你的应用的特定消息和格式)。
1. 设置依赖
Section titled “1. 设置依赖”将必要的包添加到你的 pubspec.yaml 中:
dependencies: flutter: sdk: flutter # Provides Material/Cupertino localizations flutter_localizations: sdk: flutter # Core internationalization utilities (messages, date/number formatting) intl: ^0.18.0 # Use latest version
# Add this section to enable code generation for intlflutter: uses-material-design: true generate: true # Required for intl code generation运行 flutter pub get。
2. 配置 MaterialApp
Section titled “2. 配置 MaterialApp”在你的 MaterialApp(或 CupertinoApp)中,配置本地化委托(localization delegates)和支持的语言环境(supported locales):
import 'package:flutter/material.dart';import 'package:flutter_localizations/flutter_localizations.dart';// Import generated messages (will be created later)import 'package:flutter_gen/gen_l10n/app_localizations.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'i18n Demo App', // Title might also need localization
// Define supported locales supportedLocales: const [ Locale('en', ''), // English, no country code Locale('es', ''), // Spanish, no country code // Add other locales your app supports ],
// Define localization delegates localizationsDelegates: const [ AppLocalizations.delegate, // Your app's specific messages GlobalMaterialLocalizations.delegate, // Built-in Material widgets translations GlobalWidgetsLocalizations.delegate, // Text direction, etc. GlobalCupertinoLocalizations.delegate, // Built-in Cupertino widgets translations ],
// Optional: Force a locale (for testing) or let Flutter decide // locale: Locale('es', ''),
home: MyHomePage(), ); }}3. 为消息创建 ARB 文件
Section titled “3. 为消息创建 ARB 文件”应用资源包(Application Resource Bundle,.arb)文件以 JSON 格式存储你的本地化消息。
-
在项目根目录(与
pubspec.yaml并列)创建一个名为l10n.yaml的新文件。配置它以指定模板 ARB 文件和输出目录: -
创建
arb-dir中指定的目录(例如,lib/l10n)。 -
在
lib/l10n中,创建模板 ARB 文件(本例中为app_en.arb)。此文件定义消息键、默认文本(英语)和可选描述: -
为其他支持的语言环境创建翻译文件(例如,
app_es.arb)。复制app_en.arb中的键并提供翻译:
4. 生成本地化代码
Section titled “4. 生成本地化代码”每当你修改 ARB 文件或 l10n.yaml 时,Flutter 会自动生成所需的 Dart 代码(这得益于 pubspec.yaml 中的 generate: true)。如果它没有自动运行,你可能需要触发构建或手动运行 flutter gen-l10n。
这会在 flutter_gen 目录(通常在项目视图中隐藏,但可以通过 import 访问)中生成文件,包括 app_localizations.dart 和特定语言环境的类。
5. 在 Widgets 中使用本地化消息
Section titled “5. 在 Widgets 中使用本地化消息”导入生成的 AppLocalizations 类,并使用 AppLocalizations.of(context)!.messageKey 访问消息。
import 'package:flutter/material.dart';// Import generated messagesimport 'package:flutter_gen/gen_l10n/app_localizations.dart';
class MyHomePage extends StatelessWidget { @override Widget build(BuildContext context) { // Access the localizations object final l10n = AppLocalizations.of(context)!; String userName = 'Flutter Dev'; // Example user name int wombatCount = 2;
return Scaffold( // Use localized app title appBar: AppBar(title: Text(l10n.appTitle)), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ // Use localized greeting Text(l10n.helloWorld), const SizedBox(height: 10), // Use localized message with placeholder Text(l10n.helloUser(userName)), const SizedBox(height: 10), // Use localized plural message Text(l10n.nWombats(wombatCount)), ], ), ), ); }}6. 测试不同语言环境
Section titled “6. 测试不同语言环境”- 设备设置: 更改测试设备或模拟器的语言设置。
locale属性: 在开发期间,暂时设置MaterialApp中的locale属性以强制使用特定语言环境。
日期、数字和货币格式化
Section titled “日期、数字和货币格式化”intl 包还提供了日期、数字和货币的语言环境感知格式化功能。
import 'package:intl/intl.dart';
// Inside a widget or function where 'context' is availablevoid showFormattedData(BuildContext context) { final currentLocale = Localizations.localeOf(context).toString(); // e.g., 'en_US', 'es'
// Date Formatting final now = DateTime.now(); final dateFormatter = DateFormat.yMMMd(currentLocale); // Locale-aware format print('Formatted Date: ${dateFormatter.format(now)}');
// Number Formatting final number = 1234567.89; final numberFormatter = NumberFormat.decimalPattern(currentLocale); print('Formatted Number: ${numberFormatter.format(number)}');
// Currency Formatting final currencyFormatter = NumberFormat.currency(locale: currentLocale, symbol: '€'); // Example symbol print('Formatted Currency: ${currencyFormatter.format(number)}');}国际化对于触及更广泛的受众至关重要。Flutter 的内置支持和 intl 包提供了一个强大的框架来管理翻译和特定于语言环境的数据。