Flutter字符串翻译扩展插件插件tr_extension的使用

发布于 1周前 作者 eggper 最后一次编辑是 5天前 来自 Flutter

Flutter字符串翻译扩展插件插件tr_extension的使用

tr_extension简介

tr_extension 是一个智能且轻量级的字符串翻译扩展插件。它通过扩展方法简化了Flutter应用中的多语言支持,具有以下特点:

  • 简化设置:无需额外的Widget,几行代码即可完成配置。
  • 智能回退模式:支持键值匹配,可以使用具体或通用的键。
  • 参数替换:支持JSON文件中的参数替换和复数形式处理。
  • 自动同步Locale:设置Locale后,应用会自动反映更改。
  • Flutter集成:与Flutter SDK的Widgets和flutter_localizations无缝集成。
  • 热重载友好:可以在不重启应用的情况下更新翻译内容。

快速开始

1. 配置文件

pubspec.yaml 文件中添加 tr_extension 依赖:

dependencies:
  tr_extension: ^0.5.1

同时,在 pubspec.yaml 中指定翻译文件的路径(默认为 assets/translations/):

flutter:
  assets:
     - assets/translations/

注意:当更改路径时,必须同时更改 TrDelegate 工厂构造函数中的路径,并重新编译应用。

.json 文件放在相应的文件夹中,文件名应为对应的语言代码,例如:

  • assets/translations/en_US.json
  • assets/translations/pt-BR.json

每个 .json 文件应包含键值对,其中键是翻译键,值是翻译内容。例如:

{
  "hello_world": "Hello World!"
}

分隔符允许使用:_, -, +, ., /, |, \ 和空格。

2. 设置应用

MaterialApp 中配置 localizationsDelegateslocale

MaterialApp(
  localizationsDelegates: TrDelegate(path: 'assets/translations/').toList(), // 包含 flutter_localizations
  locale: context.locale, // 自动状态管理
  supportedLocales: const [
    Locale('en', 'US'),
    Locale('pt', 'BR'),
  ],
  home: const Home(),
);

flutter_localizations 的委托已包含在 .toList() 中。

使用方法

通过在任何字符串上添加 .tr.trn 来获取对应的翻译:

  • .tr:如果未找到键,则返回相同的字符串。
  • .trn:如果未找到键,则返回 null

示例:

Text('helloWorld'.tr); // 输出: 'Hello World!'
Text('helloUniverse'.trn ?? 'other'); // 输出: 'other'

回退模式

回退模式会在找不到完整的键时,尝试匹配更通用的键:

  • [.tr]: 'a.b.c' -> 'a.b' -> 'a' -> 'a.b.c'
  • [.trn]: 'a.b.c' -> 'a.b' -> 'a' -> null

例如,对于以下翻译:

{
  "form.invalid": "This field is invalid",
  "form.invalid.email": "Invalid email"
}

结果如下:

'form.invalid.email'.tr // 'Invalid email'
'form.invalid.name'.tr // 'This field is invalid'
'form.invalid'.tr // 'This field is invalid'

参数替换

tr_extension 支持参数替换和复数形式处理。假设你有以下 JSON 文件:

{
  "user_title.{name}.male": "{name} is nominated for Best Actor",
  "user_title.{name}.female": "{name} is nominated for Best Actress",
  "user_title.{name}": "{name} is nominated for Best Actor/Actress",
  "user_description.male": "He is the favorite this year!",
  "user_description.female": "She is the favorite this year!",
  "user_description": "They are the favorite this year!",
  "user_oscars.{name}.0": "{name} still hasn't won an Oscar.",
  "user_oscars.{name}.1": "This is {name}'s first Oscar!",
  "user_oscars.{name}.{}": "{name} has won {} Oscars"
}

你可以轻松地替换参数并结合回退模式使用:

final name = 'Emma Stone';
final gender = 'female';
final oscars = 1;

print('user_title.$name.$gender'.tr); // 'Emma Stone is nominated for Best Actress'
print('user_description.$gender'.tr); // 'She is the favorite this year!'
print('user_oscars.$name.$oscars'.tr); // 'This is Emma Stone's first Oscar!'

实例方法

你可以使用 TrDelegate.instanceLocalizations.of<TrDelegate>(context, TrDelegate) 来获取 TrDelegate 的实例。常用的方法包括:

  • .setLocale(Locale locale):更改语言。
  • .setTranslations(Locale locale, Map translations):手动配置翻译(推荐使用 JSON 文件)。

以及以下 getter:

  • .translations:所有解析后的翻译。
  • .missingTranslations:所有缺失的翻译。
  • .translationFiles:所有 JSON 文件。
  • .locale:当前的 Locale。
  • .supportedLocales:所有支持的 Locale。

完整示例 Demo

以下是一个完整的示例应用,展示了如何使用 tr_extension 进行多语言支持:

import 'package:flutter/material.dart';
import 'package:tr_extension/tr_extension.dart';

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: TrDelegate().toList(),
      locale: context.locale,
      supportedLocales: const [
        Locale('en', 'US'),
        Locale('pt', 'BR'),
      ],
      home: const Home(),
    );
  }
}

class Home extends StatelessWidget {
  const Home({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            /// 这些键位于:
            /// - assets/translations/en_US.json
            /// - assets/translations/pt_BR.json
            Text('hello_world'.tr),
            Text(DateTime.now().jms()), // 格式化日期时间
            Text('1200000000.4'.compactSimpleCurrency()), // 简单货币格式化
            Text('1200000000.4'.compactCurrency()), // 货币格式化
            ElevatedButton(
              onPressed: () {
                final newLocale = context.locale == const Locale('pt', 'BR')
                    ? const Locale('en', 'US')
                    : const Locale('pt', 'BR');

                context.setLocale(newLocale);
              },
              child: Text('change_language'.tr), // 切换语言按钮
            )
          ],
        ),
      ),
    );
  }
}

更多关于Flutter字符串翻译扩展插件插件tr_extension的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

回到顶部