Flutter本地化管理插件localization_plus的使用
Flutter本地化管理插件localization_plus的使用
简介
localization_plus
是一个用于 Flutter 应用程序的国际化插件。它支持多种语言、复杂规则的复数处理、设备语言检测等功能。
安装
首先,在 pubspec.yaml
文件中添加依赖:
dependencies:
localization_plus: <last_version>
创建包含翻译文件的目录结构:
i18n
├── en.json
└── en-US.json
在 pubspec.yaml
中声明资源目录:
flutter:
assets:
- i18n/
iOS 注意事项
对于 iOS 设备,需要在 ios/Runner/Info.plist
文件中添加支持的语言:
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>nb</string>
</array>
使用示例
以下是一个完整的示例,展示如何使用 localization_plus
插件进行国际化。
初始化控制器
import 'package:flutter/material.dart';
import 'package:localization_plus/localization_plus.dart';
import 'package:get_it/get_it.dart';
GetIt getIt = GetIt.instance;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
LocalizationPlusController controller = await LocalizationPlusController.init(
path: 'i18n',
supportedLocales: [
'en_US'.toLocale(),
'ar_SA'.toLocale(),
'tr_TR'.toLocale(),
'ru_RU'.toLocale(),
],
fallbackLocale: 'en_US'.toLocale(),
useFallbackTranslations: true,
);
getIt.registerLazySingleton<LocalizationPlusController>(() => controller);
runApp(
LocalizationPlus(
controller: getIt<LocalizationPlusController>(),
child: const MyApp(),
),
);
}
主应用页面
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.currentLocale,
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
主页面状态
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int counter = 0;
Map<String, String> languageTitles = {
'tr_TR': 'Türkçe (Türkiye)',
'en_US': 'English (United States)',
'ar_SA': 'العربية (المملكة العربية السعودية)',
'ru_RU': 'русский (Россия)',
};
@override
void initState() {
super.initState();
getIt<LocalizationPlusController>().addListener(() {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(context.currentLocale.toString()),
),
);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('hello'.trans()),
actions: [
TextButton(
child: Text(languageTitles[context.currentLocale.toString()]!),
onPressed: () => showLanguageDialog(context),
)
],
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Card(
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Text('notations'.trans(arguments: {'arg': 'test'})),
const SizedBox(height: 10),
Text(trans('welcome', arguments: {'username': 'fatih'})),
const SizedBox(height: 10),
Text('goodbye'.trans(arguments: {'username': 'fatih'})),
const SizedBox(height: 10),
Text('locale'.trans(arguments: {'language': context.currentLocale.toString()})),
const SizedBox(height: 10),
Text('I love programming.'.trans()),
const SizedBox(height: 10),
Text('${'user.profile.firstname'.trans()} ${'user.profile.lastname'.trans()}'),
const SizedBox(height: 10),
const Text('fallback').trans(),
const SizedBox(height: 10),
Text(ResponseStatusType.serverError.description),
],
),
),
),
const SizedBox(height: 10),
Card(
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Text('price'.transChoice(counter)),
const SizedBox(height: 10),
Text('clicked'.plural(counter)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
FilledButton(
onPressed: () => counter > 0 ? setState(() => counter--) : null,
child: const Icon(Icons.exposure_minus_1),
),
Text(counter.toString()),
FilledButton(
onPressed: () => counter < 15 ? setState(() => counter++) : null,
child: const Icon(Icons.exposure_plus_1),
),
],
)
],
),
),
)
],
),
),
),
);
}
void showLanguageDialog(BuildContext context) {
showDialog<void>(
context: context,
builder: (BuildContext context) => AlertDialog(
contentPadding: EdgeInsets.zero,
content: SingleChildScrollView(
child: Column(
children: context.supportedLocales
.map(
(locale) => ListTile(
title: Text(languageTitles[locale.toString()].toString()),
selected: locale == context.currentLocale,
onTap: () {
Navigator.pop(context);
context.setLocale(locale);
},
),
)
.toList(),
),
),
),
);
}
}
功能说明
改变语言
你可以通过 BuildContext
或者 controller
来改变语言:
// 通过上下文
context.setLocale('en_US'.toLocale());
// 通过控制器
controller.setLocale('en_US'.toLocale());
重置语言
可以通过 resetLocale()
方法来重置语言到初始值:
// 通过上下文
context.resetLocale();
// 通过控制器
controller.resetLocale();
删除保存的语言
可以通过 deleteSavedLocale()
方法来删除保存的语言:
// 通过上下文
context.deleteSavedLocale();
// 通过控制器
controller.deleteSavedLocale();
获取当前语言
可以通过 currentLocale
方法来获取当前语言:
// 通过上下文
context.currentLocale;
// 通过控制器
controller.currentLocale;
获取设备语言
可以通过 deviceLocale
方法来获取设备语言:
// 通过上下文
context.deviceLocale
// 通过控制器
controller.deviceLocale
获取备用语言
可以通过 fallbackLocale
方法来获取备用语言:
// 通过上下文
context.fallbackLocale
// 通过控制器
controller.fallbackLocale
翻译字符串
使用 trans()
方法来翻译字符串:
// 字符串
'notations'.trans(arguments: {'arg': 'test'})
// Text 组件
const Text('notations').trans(arguments: {'arg': 'test'})
// 帮助函数
trans('notations', arguments: {'arg': 'test'})
复数处理
使用 plural()
方法来处理复数形式:
// 字符串
'clicked'.plural(0) // Today
'clicked'.plural(1) // Tomorrow
'clicked'.plural(2) // 2 days later
'clicked'.plural(3) // A few days later (根据语言)
'clicked'.plural(11) // Weeks later (根据语言)
'clicked'.plural(1250) // After a long time (根据语言)
选择性翻译
使用 transChoice()
方法来处理选择性翻译:
// 字符串
'price'.transChoice(0) // Free
'price'.transChoice(1) // Cheap
'price'.transChoice(3) // Cheap
'price'.transChoice(6) // Normal
'price'.transChoice(10) // Normal
'price'.transChoice(1250) // Expensive
监听语言变化
可以通过 addListener()
方法来监听语言变化:
controller.addListener(() {
// 语言已更改
// 重新加载与语言相关的远程数据等
});
链接翻译
如果某个翻译总是与另一个翻译相同,可以使用链接翻译:
{
"hello": "Hello",
"world": "World",
"hello_world": "@:hello @:world"
}
检查翻译是否存在
可以使用 transExists()
方法来检查翻译是否存在:
'notations'.transExists() // true
transExists('not_exists') // false
扩展功能
字符串扩展
'en_US'.toLocale(); // Locale('en', 'US')
// 自定义分隔符
'en|US'.toLocale(separator: '|') // Locale('en', 'US')
枚举扩展
{
"enums": {
"response_status_type": {
"successful": "Successful",
"server_error": "Server Error"
}
},
}
// 枚举值
ResponseStatusType.successful.description; // Successful
ResponseStatusType.serverError.description; // Server Error
BuildContext 扩展
context.currentLocale // 获取当前语言
context.deviceLocale // 获取设备语言
context.fallbackLocale // 获取备用语言
context.supportedLocales // 获取支持的语言
context.localizationDelegates // 获取本地化代理
更多关于Flutter本地化管理插件localization_plus的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter本地化管理插件localization_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
localization_plus
是一个用于 Flutter 应用的本地化管理的插件,它可以帮助开发者轻松地实现多语言支持。以下是关于如何使用 localization_plus
插件的详细步骤。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 localization_plus
插件的依赖:
dependencies:
flutter:
sdk: flutter
localization_plus: ^1.0.0 # 请检查最新版本
然后运行 flutter pub get
来获取依赖包。
2. 创建本地化文件
在项目中创建一个文件夹来存放本地化文件,例如 lib/l10n
。然后为每种支持的语言创建一个 JSON 文件。例如:
lib/l10n/en.json
(英语)lib/l10n/es.json
(西班牙语)
这些 JSON 文件的内容将包含键值对,表示不同语言的翻译。例如:
lib/l10n/en.json
:
{
"hello": "Hello",
"welcome": "Welcome to the app"
}
lib/l10n/es.json
:
{
"hello": "Hola",
"welcome": "Bienvenido a la aplicación"
}
3. 初始化 LocalizationPlus
在你的 main.dart
文件中,初始化 LocalizationPlus
,并设置默认语言和可用的语言列表:
import 'package:flutter/material.dart';
import 'package:localization_plus/localization_plus.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await LocalizationPlus.init(
defaultLang: 'en', // 默认语言
supportedLangs: ['en', 'es'], // 支持的语言列表
assetsDir: 'lib/l10n', // 本地化文件所在的目录
);
runApp(MyApp());
}
4. 使用 LocalizationPlus
在你的应用中使用 LocalizationPlus
来获取翻译文本。你可以通过 LocalizationPlus.instance.translate
方法来获取特定键的翻译。
import 'package:flutter/material.dart';
import 'package:localization_plus/localization_plus.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Localization Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(LocalizationPlus.instance.translate('hello')),
Text(LocalizationPlus.instance.translate('welcome')),
],
),
),
),
);
}
}
5. 切换语言
你可以在运行时切换应用的语言。例如,通过按钮切换语言:
import 'package:flutter/material.dart';
import 'package:localization_plus/localization_plus.dart';
class LanguageSwitcher extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: () async {
await LocalizationPlus.instance.setLanguage('en');
},
child: Text('English'),
),
ElevatedButton(
onPressed: () async {
await LocalizationPlus.instance.setLanguage('es');
},
child: Text('Spanish'),
),
],
);
}
}
6. 监听语言变化
如果你希望在语言变化时更新 UI,可以使用 LocalizationPlus.instance.onLocaleChanged
监听器:
LocalizationPlus.instance.onLocaleChanged.listen((locale) {
// 更新 UI 或执行其他操作
});