为您的Flutter应用提供简单、高级、快速的国际化支持
关于此库
- ✅ 完全测试的代码(100%代码覆盖率)
- ? 支持多种语言的简单翻译
- ?️ 空安全
- ? 从JSON文件加载翻译
- ? BuildContext, String 和 Text 的扩展方法
- ? 支持复数、嵌套、选择、RTL区域设置等
- ↩️ 回退区域设置键重定向(可选)
- ? 持久的区域设置存储(可选)
- ❗ 丢失翻译的错误小部件
- ? 通过控制器监听本地化更改
- ? 通过控制器独立于上下文的区域设置更改
安装
添加到您的 pubspec.yaml
dependencies:
localization_plus: <last_version>
创建文件夹并像这样添加翻译文件
i18n
├── {languageCode}.{ext} // useOnlyLangCode: true
└── {languageCode}-{countryCode}.{ext} // useOnlyLangCode: false (default)
示例
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>
文档
? LocalizationPlusController 属性
| 属性 | 必需 | 默认值 | 描述 |
|---|---|---|---|
| supportedLocales | 真 | 支持的区域设置列表。 | |
| path | 真 | 包含本地化文件的文件夹路径。 | |
| loader | 假 | RootBundleAssetLoader() |
本地化文件的类加载器。您可以创建自己的类。 |
| saveLocale | 假 | 真 |
更改语言后是否保存在设备上 |
| useOnlyLangCode | 假 | 假 |
用于仅使用语言代码读取本地化文件的触发器。示例:en.json //useOnlyLangCode: trueen-US.json //useOnlyLangCode: false (默认) |
| useFallbackTranslations | 假 | 假 |
如果在区域设置文件中找不到本地化键,请尝试使用回退区域设置文件。如果未设置回退区域设置,则将第一个支持的语言设置为回退 |
| fallbackLocale | 假 | 设置在区域设置文件中找不到本地化键时要用作替代的区域设置 | |
| startLocale | 假 | 如果没有保存的语言,则设置系统将启动的语言 |
? LocalizationPlus 小部件属性
| 属性 | 必需 | 默认值 | 描述 |
|---|---|---|---|
| key | 假 | 小部件键。 | |
| child | 真 | 放置您的主页面小部件的地方。 | |
| 控制器 | 真 | LocalizationPlusController 实例。 |
替换翻译字符串中的参数
如果需要,可以在翻译字符串中定义占位符。所有占位符都必须放在花括号中。例如,您可以定义一个带有占位符名称的欢迎消息
{
"welcome": "Welcome, {name}"
}
如果您的占位符全部大写,或者只有首字母大写,翻译后的值也将相应大写
"welcome": "Welcome, {NAME}" // Welcome, USER
"welcome": "Welcome, {Name}" // Welcome, User
用法/示例
import 'package:flutter/material.dart';
import 'package:localization_plus/localization_plus.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// If you wish, you can define it so that it can be accessed
// from anywhere in the system with a package such as the getIt library
LocalizationPlusController controller = await LocalizationPlusController.init(
path: 'i18n',
);
runApp(
LocalizationPlus(
controller: controller,
supportedLocales: [
'en_US'.toLocale(),
'ar_DZ'.toLocale(),
'tr_TR'.toLocale(),
'ru_RU'.toLocale(),
],
child: const MyApp()
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// Localizations
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: MyHomePage()
);
}
}
? 更改区域设置
您可以通过 BuildContext 扩展方法或控制器来更改区域设置。
// via context
context.setLocale('en_US'.toLocale());
// via controller
controller.setLocale('en_US'.toLocale());
? 重置区域设置 resetLocale()
将区域设置重置为初始区域设置。如果定义了 startLocale,则将其设置为 startLocale;如果未定义,则设置为 deviceLocale。
// via context
context.resetLocale()
// via controller
controller.resetLocale();
? 删除已保存的区域设置 deleteSavedLocale()
清除本地存储中已保存的区域设置
// via context
context.deleteSavedLocale()
// via controller
controller.deleteSavedLocale();
? 获取区域设置 currentLocale
返回应用程序中的当前区域设置
// via context
context.currentLocale;
// via controller
controller.currentLocale;
? 获取设备区域设置 deviceLocale
返回设备区域设置
// via context
context.deviceLocale
// via controller
controller.deviceLocale
? 获取回退区域设置 fallbackLocale
返回回退区域设置。如果 useFallbackTranslations 为 false,则返回 null。
// via context
context.fallbackLocale
// via controller
controller.fallbackLocale
? 翻译 trans()
翻译语言键的主要函数
您可以使用 [String] 或 [Text] 小部件的扩展方法,您也可以使用 trans() 作为辅助函数。
示例
{
"notations": "Default: {arg}, Capital: {Arg}, Uppercase: {ARG}",
}
'notations'.trans(arguments: {'arg': 'test'}) // String
// Result: Default: test, Capital: Test, Uppercase: TEST
const Text('notations').trans(arguments: {'arg': 'test'}) // Text
// Result: Text instance
trans('notations', arguments: {'arg': 'test'}) // Helper function
// Result: Default: test, Capital: Test, Uppercase: TEST
参数
| 名称 | 类型 | 描述 |
|---|---|---|
| arguments | Map<String, String> |
本地化字符串的映射。根据其名称替换名称键 {key_name}。 |
? 复数 plural()
复数是一个复杂的问题,因为不同语言的复数规则多种多样;然而,Localization Plus 可以帮助您根据您定义的复数规则以不同的方式翻译字符串。
您可以使用 [String] 或 [Text] 小部件的扩展方法,您也可以使用 plural() 作为辅助函数。
? 必需的“other”键!
示例
{
"clicked": {
"zero": "Today",
"one": "Tomorrow",
"two": "2 days later",
"few": "A few days later",
"many": "Weeks later",
"other": "After a long time"
}
}
// String
'clicked'.plural(0) // Today
'clicked'.plural(1) // Tomorrow
'clicked'.plural(2) // 2 days late
'clicked'.plural(3) // A few days later (Depends on the language)
'clicked'.plural(11) // Weeks later (Depends on the language)
'clicked'.plural(1250) // After a long time (Depends on the language)
// Text
Text('clicked').plural(0) // Today
Text('clicked').plural(1) // Tomorrow
Text('clicked').plural(2) // 2 days late
Text('clicked').plural(3) // A few days later (Depends on the language)
Text('clicked').plural(11) // Weeks later (Depends on the language)
Text('clicked').plural(1250) // After a long time (Depends on the language)
plural('clicked', 0) // Today
plural('clicked', 1) // Tomorrow
plural('clicked', 2) // 2 days late
plural('clicked', 3) // A few days later (Depends on the language)
plural('clicked', 11) // Weeks later (Depends on the language)
plural('clicked', 1250) // After a long time (Depends on the language)
参数
| 名称 | 类型 | 描述 |
|---|---|---|
| arguments | Map<String, String> |
本地化字符串的映射。根据其名称替换名称键 {key_name}。 |
? 翻译选择 transChoice()
您可以创建更复杂的复数规则,为多个值的范围指定翻译字符串。
您可以使用 [String] 或 [Text] 小部件的扩展方法,您也可以使用 transChoice() 作为辅助函数。
示例
{
"price": {
"0": "Free",
"1:5": "Cheap",
"6:10": "Normal",
"*": "Expensive"
}
}
// String
'price'.transChoice(0) // Free
'price'.transChoice(1) // Cheap
'price'.transChoice(3) // Cheap
'price'.transChoice(6) // Normal
'price'.transChoice(10) // Normal
'price'.transChoice(1250) // Expensive
// Text
('price').transChoice(0) // Free
('price').transChoice(1) // Cheap
('price').transChoice(3) // Cheap
('price').transChoice(6) // Normal
('price').transChoice(10) // Normal
('price').transChoice(1250) // Expensive
transChoice('price', 0) // Free
transChoice('price', 1) // Cheap
transChoice('price', 3) // Cheap
transChoice('price', 6) // Normal
transChoice('price', 10) // Normal
transChoice('price', 1250) // Expensive
参数
| 名称 | 类型 | 描述 |
|---|---|---|
| arguments | Map<String, String> |
本地化字符串的映射。根据其名称替换名称键 {key_name}。 |
? 监听区域设置更改
您可以通过控制器来监听区域设置更改。
controller.addListener(() {
// Locale changed
// Refetch language dependent remote data etc.
});
? 链接翻译
如果有一个翻译键将始终具有与另一个键相同的具体文本,您可以直接链接到它。要链接到另一个翻译键,您所要做的就是在其内容前加上 @: 符号,后跟您想要链接的完整翻译键名称,包括命名空间。
{
"hello": "Hello",
"world": "World",
"hello_world": "@:hello @:world"
}
您还可以在链接的消息中包含嵌套的匿名和命名参数。
格式化链接翻译
如果语言区分字符大小写,您可能需要控制链接区域设置消息的大小写。可以使用修饰符 @.modifier:key 格式化链接消息。
目前可用的修饰符如下。
upper: 将链接消息中的所有字符转换为大写。lower: 将链接消息中的所有字符转换为小写。capitalize: 将链接消息的首字母大写。
示例
{
...
"hello": "Hello",
"world": "World",
"hello_world": "@.upper:hello @.lower:world" // HELLO world
...
}
? 检查翻译是否存在 transExists()
您可以检查一个键是否具有翻译
'notations'.transExists() // String
// Result: true
transExists('not_exists') // Helper function
// Result: false
? 扩展
String 扩展
'en_US'.toLocale(); // Locale('en', 'US')
//with custom separator
'en|US'.toLocale(separator: '|') // Locale('en', 'US')
Build Context 扩展
context.currentLocale // get current locale
context.deviceLocale // get device locale
context.fallbackLocale // get fallback locale
context.supportedLocales // get supported locales
context.localizationDelegates // get localization delegates
屏幕截图
| 阿拉伯语 RTL | 英语 LTR | 土耳其语 LTR | 俄语 LTR |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |



