fast_i18n

轻量级 i18n 解决方案。使用 JSON 文件创建类型安全的翻译。

入门

步骤 1:添加依赖项

dependencies:
  fast_i18n: ^3.0.2

dev_dependencies:
  build_runner: any

步骤 2:创建 JSON 文件

在您的 lib 目录中创建这些文件。最好放在一个公共包中,例如 lib/i18n
只有扩展名为 .i18n.json 的文件才会被检测到。您可以 进行配置

strings.i18n.json (默认,回退)

{
  "hello": "Hello $name",
  "save": "Save",
  "login": {
    "success": "Logged in successfully",
    "fail": "Logged in failed"
  }
}

strings_de.i18n.json

{
  "hello": "Hallo $name",
  "save": "Speichern",
  "login": {
    "success": "Login erfolgreich",
    "fail": "Login fehlgeschlagen"
  }
}

步骤 3:生成 Dart 代码

flutter pub run build_runner build

步骤 4:初始化

a) 使用设备 locale

void main() {
  WidgetsFlutterBinding.ensureInitialized(); // add this
  LocaleSettings.useDeviceLocale(); // and this
  runApp(MyApp());
}

b) 使用特定的 locale

@override
void initState() {
  super.initState();
  String storedLocale = loadFromStorage(); // your logic here
  LocaleSettings.setLocale(storedLocale);
}

步骤 4a:覆盖 'supportedLocales'

这是可选的,但推荐这样做。

标准的 Flutter 控件(例如,后退按钮的工具提示)也会选择正确的 locale。

MaterialApp(
  localizationsDelegates: const [
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
  supportedLocales: LocaleSettings.supportedLocales, // <---
)

步骤 4b:iOS 配置

File: ios/Runner/Info.plist

<key>CFBundleLocalizations</key>
<array>
   <string>en</string>
   <string>de</string>
</array>

步骤 5:使用您的翻译

Text(t.login.success); // plain
Text(t.hello(name: 'Tom')); // with argument
Text(t.step[3]); // with index (for arrays)
Text(t.type['WARNING']); // with key (for maps)

// advanced
TranslationProvider(child: MyApp()); // wrap your app with TranslationProvider
// [...]
final t = Translations.of(context); // forces a rebuild on locale change
String translateAdvanced = t.hello(name: 'Tom');

API

Dart 代码生成后,您会看到一些有用的类和函数

t - 用于简单翻译的翻译变量

Translations.of(context) - 对 locale 更改做出反应的翻译

TranslationProvider - 应用包装器,用于 Translations.of(context)

LocaleSettings.useDeviceLocale() - 使用设备的 locale

LocaleSettings.setLocale('de') - 更改 locale

LocaleSettings.setLocaleTyped(AppLocale.en) - 更改 locale(类型化版本)

LocaleSettings.currentLocale - 获取当前 locale

LocaleSettings.currentLocaleTyped - 获取当前 locale(类型化版本)

LocaleSettings.locales - 获取支持的 locales

LocaleSettings.supportedLocales - 请参阅步骤 4a

配置

所有设置都可以在 build.yaml 文件中进行设置。将其放在根目录下。

targets:
  $default:
    builders:
      fast_i18n:i18nBuilder:
        options:
          base_locale: en
          input_directory: lib/i18n
          input_file_pattern: .i18n.json
          output_directory: lib/i18n
          output_file_pattern: .g.dart
          translate_var: t
          enum_name: AppLocale
          key_case: snake
          maps:
            - a
            - b
            - c.d
按键 类型 用法 默认值
base_locale 字符串 默认 JSON 的 locale en
input_directory 字符串 输入目录的路径
input_file_pattern 字符串 输入文件的模式 .i18n.json
output_directory 字符串 输出目录的路径
output_file_pattern 字符串 输出文件的模式 .g.dart
translate_var 字符串 翻译变量名 t
enum_name 字符串 枚举名 AppLocale
key_case camel, pascal, snake 转换键(可选)
maps List<String> 应通过键访问的条目 []

常见问题

如何添加参数?

使用 $ 前缀。

在边缘情况下,您也可以将其包装在 ${...} 中。

{
  "greeting": "Hello $name",
  "distance": "${distance}m"
}
t.greeting(name: 'Tom'); // Hello Tom
t.distance(distance: 4.5); // 4.5m

如何通过 maps 访问翻译?

在您的 build.yaml 中定义 maps。
请记住,像自动完成这样的所有酷炫功能都消失了。

strings.i18n.json

{
  "welcome": "Welcome",
  "thisIsAMap": {
    "hello world": "hello"
  },
  "classicClass": {
    "hello": "hello",
    "aMapInClass": {
      "hi": "hi"
    }
  }
}

build.yaml

targets:
  $default:
    builders:
      fast_i18n:i18nBuilder:
        options:
          maps:
            - thisIsAMap
            - classicClass.aMapInClass

现在您可以通过键访问翻译

String a = t.thisIsAMap['hello world'];
String b = t.classicClass.hello; // the "classical" way
String c = t.classicClass.aMapInClass['hi']; // nested

可以使用列表吗?

列表得到完全支持。您也可以将列表或 maps 放入列表!

{
  "niceList": [
    "hello",
    "nice",
    [
      "first item in nested list",
      "second item in nested list"
    ],
    {
      "wow": "WOW!",
      "ok": "OK!"
    },
    {
      "a map entry": "access via key",
      "another entry": "access via second key"
    }
  ]
}
String a = t.niceList[1]; // "nice"
String b = t.niceList[2][0]; // "first item in nested list"
String c = t.niceList[3].ok; // "OK!"
String d = t.niceList[4]['a map entry']; // "access via key"

GitHub

https://github.com/Tienisto/flutter-fast-i18n