Flutter国际化插件fluent_i18n的使用
Flutter国际化插件fluent_i18n的使用
为什么选择fluent_i18n?
有时你希望在没有上下文的情况下访问本地化文本,例如在模型类中。这个包使用单例模式加载Fluent Translation List (FTL)文件。你可以无需上下文即可访问本地化字符串(当然,也可以通过上下文访问),它还提供了更方便的方法,减少代码量并使应用程序的所有部分都能本地化。
开始使用
安装
在pubspec.yaml
中添加依赖:
dependencies:
fluent_i18n: <最新版本>
创建文件夹并添加翻译文件,结构如下:
assets
└── i18n
├── {languageCode}.ftl //仅语言代码
└── {languageCode}_countryCode}.ftl //或完整区域代码
例如:
assets
└── i18n
├── en.ftl
└── en_US.ftl
在pubspec.yaml
中声明你的资源本地化目录:
flutter:
assets:
- assets/i18n/
iOS注意事项
为了使翻译在iOS上生效,你需要在ios/Runner/Info.plist
中添加支持的区域设置:
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>ja</string>
</array>
配置应用
在应用中添加EasyLocalization
小部件,示例如下:
import 'package:fluent_i18n/fluent_i18n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
const List<Locale> SUPPORTED_LOCALES = [
const Locale('ja'),
const Locale('en'),
];
Locale locale = SUPPORTED_LOCALES.first;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
locale: locale,
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
FluentLocalizationsDelegate(SUPPORTED_LOCALES),
],
supportedLocales: SUPPORTED_LOCALES,
);
}
}
使用
更改区域设置 setLocale()
你可以通过调用以下方法更改区域设置:
await FluentLocalizations.setLocale(locale);
这将更改当前区域设置并加载相应的FTL文件。
或者,你可以调用(这是setLocale()
所做的):
await FluentLocalizations.ofLocale(locale).load();
翻译 getMessage()
主要的翻译函数是getMessage()
,示例如下:
final i18n = FluentLocalizations.current();
Text(i18n.getMessage('home-title'))
如果你自己维护区域设置,可以使用:
final i18n = FluentLocalizations.ofLocale(currentLocale);
...
// 某处加载
await i18n.load();
...
Text(i18n.getMessage('home-title'))
提示:不会破坏现有代码,你可以继续使用旧的静态方法FluentLocalizations.of(context)
。
完整示例Demo
以下是一个完整的示例,展示了如何使用fluent_i18n
进行国际化:
import 'package:fluent_i18n/fluent_i18n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'strings.dart'; // 假设这是你的字符串文件
const List<Locale> SUPPORTED_LOCALES = [
const Locale('ja'),
const Locale('en'),
];
Locale locale = SUPPORTED_LOCALES.first;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
onGenerateTitle: (context) => Strings.appTitle, // 从strings.dart中获取应用标题
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
locale: locale,
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
FluentLocalizationsDelegate(SUPPORTED_LOCALES),
],
supportedLocales: SUPPORTED_LOCALES,
);
}
}
class MyHomePage extends StatefulWidget {
[@override](/user/override)
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(Strings.homeTitle), // 从strings.dart中获取首页标题
),
body: Container(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
Strings.pushedButtonThisManyTimes(_counter), // 从strings.dart中获取按钮点击次数的文本
style: Theme.of(context).textTheme.titleLarge,
),
SizedBox(
height: 20.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Language: "),
DropdownButton<Locale>(
value: locale,
items: SUPPORTED_LOCALES.map((language) {
return DropdownMenuItem(
child: Text(language.toString()),
value: language,
);
}).toList(),
onChanged: (value) async {
if (value != null) {
await Strings.applyLocale(value); // 应用新的区域设置
setState(() {
locale = value;
});
}
}),
],
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: Strings.increment, // 从strings.dart中获取增量提示
child: Icon(Icons.add),
), // 这个尾随逗号使自动格式化更美观
);
}
}
更多关于Flutter国际化插件fluent_i18n的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter国际化插件fluent_i18n的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用fluent_i18n
插件进行国际化的代码示例。fluent_i18n
是一个强大的国际化插件,它允许你使用Fluent语法来定义本地化资源。
步骤 1: 添加依赖
首先,你需要在pubspec.yaml
文件中添加fluent_i18n
依赖:
dependencies:
flutter:
sdk: flutter
fluent_i18n: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
步骤 2: 创建Fluent资源文件
在你的Flutter项目根目录下创建一个locales
文件夹,并在其中创建你的Fluent资源文件。例如,你可以创建en-US.ftl
和zh-CN.ftl
文件。
en-US.ftl
greeting = Hello, { $name }!
farewell = Goodbye, { $name }!
zh-CN.ftl
greeting = 你好, { $name }!
farewell = 再见, { $name }!
步骤 3: 配置Flutter应用
在你的lib
目录下创建一个l10n
文件夹,并在其中创建一个fluent_localizations.dart
文件来配置Fluent本地化。
fluent_localizations.dart
import 'package:fluent_i18n/fluent_i18n.dart';
import 'package:flutter/material.dart';
import 'dart:io';
class FluentLocalizations {
static Future<FluentBundle> load(Locale locale) async {
var file = File('locales/${locale.languageCode}-${locale.countryCode}.ftl');
var content = await file.readAsString();
return FluentBundle.fromString(locale.toString(), content);
}
static LocalizationsDelegate<FluentBundle> delegate(Locale locale) {
return _FluentLocalizationsDelegate(locale);
}
}
class _FluentLocalizationsDelegate
extends LocalizationsDelegate<FluentBundle> {
final Locale locale;
_FluentLocalizationsDelegate(this.locale);
@override
bool isSupported(Locale locale) => true; // 或者添加你的支持逻辑
@override
Future<FluentBundle> load(Locale locale) => FluentLocalizations.load(locale);
@override
bool shouldReload(covariant LocalizationsDelegate<FluentBundle> oldDelegate) =>
false;
}
步骤 4: 使用FluentBundle进行本地化
在你的MaterialApp
中配置localizationsDelegates
和supportedLocales
,并使用FluentBundle
进行本地化。
main.dart
import 'package:flutter/material.dart';
import 'l10n/fluent_localizations.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
localizationsDelegates: [
FluentLocalizations.delegate(Locale('en', 'US')), // 默认语言
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
Locale('en', 'US'),
Locale('zh', 'CN'),
],
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Locale _locale;
@override
Widget build(BuildContext context) {
final FluentBundle bundle = Localizations.of<FluentBundle>(context, FluentBundle)!;
return Scaffold(
appBar: AppBar(
title: Text('Fluent I18n Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(bundle.getMessage('greeting', args: {'name': 'Alice'})),
ElevatedButton(
onPressed: () {
setState(() {
_locale = _locale == Locale('en', 'US')
? Locale('zh', 'CN')
: Locale('en', 'US');
Localizations.override(
context,
FluentLocalizations.delegate(_locale),
);
});
},
child: Text('Change Language'),
),
Text(bundle.getMessage('farewell', args: {'name': 'Alice'})),
],
),
),
);
}
}
在这个示例中,我们通过点击按钮来改变应用的语言。注意,由于Localizations.override
的使用可能会引发一些警告,它通常用于演示目的,在生产环境中你可能需要更复杂的逻辑来管理语言切换(例如,使用Provider或Riverpod等状态管理库)。
这个代码示例展示了如何在Flutter项目中使用fluent_i18n
插件进行国际化。你可以根据需要进一步扩展和修改它。