Flutter国际化翻译插件flutter_translaty的使用

Flutter国际化翻译插件flutter_translaty的使用

本包允许你轻松地在你的Flutter应用中使用在https://www.translaty.io?sr=0管理的翻译。
Translaty依赖于开源解决方案https://pub.dev/packages/easy_localization,用于将翻译集成到Flutter中。我们非常感谢维护者的工作,并感激他们开发了这个伟大的工具。此包是easy_localization的扩展版本,增加了Translaty特有的功能,如Over-The-Air-更新。

开始使用

Translaty设置

如果尚未完成,请在https://www.translaty.io?sr=0创建一个项目。Translaty已经为你创建了一个初始的翻译键,名为"hello_world"。你可以根据需要修改它。

在项目设置中,可以复制客户端密钥到剪贴板:

[获取客户端密钥]

Flutter设置

  1. 安装flutter_translaty包:
flutter pub add flutter_translaty
  1. 运行设置命令并传递你的密钥。这将在你的项目根目录下创建一个名为translaty.yaml的文件,其中包含相关内容:
flutter pub run flutter_translaty:setup --key "<<your_client_key>>"
  1. 运行命令以生成你的翻译文件:
flutter pub run flutter_translaty:generate
  1. assets/translations/translaty.yaml添加为资产路径到你的pubspec.yaml文件:
flutter:
  assets:
  - translaty.yaml
  - assets/translations/
  1. main()方法的开头添加以下内容:
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
  1. 使用EasyLocalization包装你的应用,确保使用你在创建项目时添加的语言环境。记住,Locale("en")Locale("en", "US")不同:
// 之前
runApp(const MyApp());

// 之后
runApp(
  EasyLocalization(
    supportedLocales: const [
      Locale('en', 'US'),
      Locale('de'),
    ],
    path: 'assets/translations',
    fallbackLocale: const Locale('en', 'US'),
    saveLocale: true,
    child: const MyApp(),
  ),
);
  1. 向你的MaterialApp添加必要的属性:
// 之前
return MaterialApp(
  home: const MyHomePage()
);

// 之后
return MaterialApp(
  localizationsDelegates: context.localizationDelegates,
  supportedLocales: context.supportedLocales,
  locale: context.locale,
  home: const MyHomePage()
);

为了测试是否正常工作,可以在文本小部件中添加一些文本:

Text(tr(LocaleKeys.hello_world)),

你需要进行一些导入声明,例如:

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

import 'generated/locale_keys.g.dart';

现在运行你的应用,你应该能看到从Translaty来的"hello world"文本。

可选:添加按钮来改变语言

添加一个按钮来改变语言。这个示例代码使用’de’语言环境,你可以将其替换为你的项目的任何其他支持的语言环境:

ElevatedButton(
  onPressed: () {
    final locales = context.supportedLocales;
    if (locales.length == 1) {
      print("无法更改语言环境,因为只有一种语言环境");
      return;
    }
    final anotherLocale = locales.firstWhere(
      (element) => element != context.locale,
    );
    context.setLocale(anotherLocale);
  },
  child: const Text("更改语言"),
),

参数

在Translaty中添加一个键,并用花括号插入参数:

[创建带参数的键]

填写所有语言的文本:

[带参数的键]

重新生成你的Flutter项目的翻译:

flutter pub run flutter_translaty:generate

使用参数的方式如下:

Text(
  tr(LocaleKeys.key_with_args, namedArgs: {
    "toolName": "Translaty",
  }),
)

复数

在Translaty中添加一个键并勾选“复数”选项:

[创建复数键]

填写所有语言的复数情况:

[复数键]

重新生成你的Flutter项目的翻译:

flutter pub run flutter_translaty:generate

使用复数键的方式如下:

Text(plural(LocaleKeys.some_plural_key, 3))

测试

通常,在执行测试时你不需要担心Translaty。但是,该包会进行真实的HTTPS调用(用于获取配置和Over-The-Air更新)。如果你想要避免这种情况,你可以创建一个OtaService的模拟。这里有一个使用mocktail的例子:

import 'package:mocktail/mocktail.dart';

class MockOtaService extends Mock implements OtaService {}

final mockOtaService = MockOtaService();
when(() => mockOtaService.init()).thenAnswer((_) => Future.value());
when(() => mockOtaService.shallExecuteOta).thenReturn(false);

然后,将此模拟传递给你的EasyLocalization小部件:

EasyLocalization(
  otaService: mockOtaService,
)

日志记录

easy_localization使用基于https://pub.dev/packages/easy_logger的日志记录器。

你可以自定义你的项目的日志记录器。

仅显示丢失的键消息

丢失的翻译键被记录为警告消息。更改[Easy Logger]级别以仅显示错误和警告:

EasyLocalization.logger.enableLevels = [LevelMessages.error, LevelMessages.warning];

关闭日志记录

要禁用日志记录,更改[Easy Logger]的构建模式为空列表:

EasyLocalization.logger.enableBuildModes = [];

捕获日志消息

要捕获日志消息,你需要覆盖默认的打印机函数:

EasyLogPrinter customLogPrinter = (
  Object object, {
  String name,
  StackTrace stackTrace,
  LevelMessages level,
}) {
  ///你的函数
  print('$name: ${object.toString()}');
};

/// 覆盖打印机为自定义
EasyLocalization.logger.printer = customLogPrinter;

easy_localization提供的其他功能

获取设备语言环境

print('${context.deviceLocale.toString()}'); // 输出: en_US

注意!也许你在Translaty中添加了"en"作为语言,但你的设备语言环境是"en_US"。在这种情况下,你需要手动进行转换。

删除保存的语言环境

清除设备存储中的保存语言环境:

ElevatedButton(
  onPressed: (){
    context.deleteSaveLocale();
  },
  child: Text(LocaleKeys.reset_locale).tr(),
)

字符串到语言环境

'en_US'.toLocale(); // Locale('en', 'US')

// 使用自定义分隔符
'en|US'.toLocale(separator: '|') // Locale('en', 'US')

语言环境到字符串(带分隔符)

Locale('en', 'US').toStringWithSeparator(separator: '|') // en|US

完整示例代码

import 'dart:developer';

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

import 'generated/locale_keys.g.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();

  runApp(
    EasyLocalization(
      supportedLocales: const [
        Locale('en'),
        Locale('de'),
        Locale('ru'),
      ],
      path: 'assets/translations',
      startLocale: const Locale('en'),
      saveLocale: false,
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: context.localizationDelegates,
      supportedLocales: context.supportedLocales,
      locale: context.locale,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int counter = 0;

  void _incrementCounter() {
    setState(() {
      counter++;
    });
  }

  void _decreaseCounter() {
    setState(() {
      counter--;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const _Title("普通翻译"),
            Text(tr(LocaleKeys.single_key)),
            const _Title("参数"),
            Text(
              tr(
                LocaleKeys.key_with_args,
                namedArgs: {'countryName': '法国', "vehicle": "自行车"},
              ),
            ),
            Text(
              tr(
                LocaleKeys.key_with_args,
                namedArgs: {'countryName': '秘鲁', "vehicle": "飞机"},
              ),
            ),
            const _Title("复数"),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () => _decreaseCounter(),
                  child: const Text("-"),
                ),
                const SizedBox(width: 32),
                Text(
                  plural(
                    LocaleKeys.plural_key,
                    counter,
                    namedArgs: {
                      "count": counter.toString(),
                    },
                  ),
                ),
                const SizedBox(width: 32),
                ElevatedButton(
                  onPressed: () => _incrementCounter(),
                  child: const Text("+"),
                ),
              ],
            ),
            const _Title("更改语言"),
            ChangeLanguageWidget(afterChange: () {
              setState(() {});
            }),
            const _Title("设备语言环境"),
            Text(context.deviceLocale.toString()),
          ],
        ),
      ),
    );
  }
}

class _Title extends StatelessWidget {
  final String text;
  const _Title(this.text, {Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            text,
            style: const TextStyle(
              fontSize: 22,
              fontWeight: FontWeight.bold,
            ),
          ),
          const Divider(
            height: 2,
            thickness: 2,
          ),
        ],
      ),
    );
  }
}

class ChangeLanguageWidget extends StatelessWidget {
  final Function() afterChange;
  const ChangeLanguageWidget({
    Key? key,
    required this.afterChange,
  }) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    final locales = context.supportedLocales;
    return Wrap(
      spacing: 8,
      children: locales.map(
        (locale) {
          return ElevatedButton(
            child: Text(locale.toLanguageTag()),
            onPressed: () async {
              log(locale.toString(), name: toString());

              await context.setLocale(locale);
              afterChange.call();
            },
          );
        },
      ).toList(),
    );
  }
}

更多关于Flutter国际化翻译插件flutter_translaty的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter国际化翻译插件flutter_translaty的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用 flutter_translaty 插件进行 Flutter 应用国际化的代码示例。flutter_translaty 是一个方便的 Flutter 国际化插件,它允许你轻松地在 Flutter 应用中实现多语言支持。

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 flutter_translaty 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_translaty: ^x.y.z  # 请替换为最新版本号

然后运行 flutter pub get 来获取依赖。

2. 设置翻译文件

在项目的 assets 文件夹下创建一个 locales 文件夹,并在其中创建不同语言的 JSON 文件。例如,创建 en.jsonzh.json 文件:

assets/locales/en.json

{
  "welcome_message": "Welcome to our app!",
  "goodbye_message": "Goodbye!"
}

assets/locales/zh.json

{
  "welcome_message": "欢迎来到我们的应用!",
  "goodbye_message": "再见!"
}

3. 配置 Flutter 应用

pubspec.yaml 中添加对翻译文件的引用:

flutter:
  assets:
    - assets/locales/en.json
    - assets/locales/zh.json

4. 初始化 FlutterTranslaty

在你的主文件(通常是 main.dart)中初始化 FlutterTranslaty

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Internationalization',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      localizationsDelegates: [
        // 添加 FlutterTranslaty 的委托
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        FlutterTranslaty.delegate,
      ],
      supportedLocales: [
        Locale('en', ''),
        Locale('zh', ''),
      ],
      locale: Locale('en'), // 默认语言
      home: MyHomePage(),
    );
  }
}

5. 使用翻译功能

在你的页面或组件中使用 FlutterTranslaty 提供的翻译功能:

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    // 获取翻译实例
    final FlutterTranslaty translate = FlutterTranslaty.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(translate('welcome_message')),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(translate('welcome_message')),
            ElevatedButton(
              onPressed: () {
                // 切换语言
                FlutterTranslaty.changeLocale(Locale('zh'));
                // 更新 UI(如果需要的话,可以通过 setState 来强制刷新)
                setState(() {});
              },
              child: Text('Switch to Chinese'),
            ),
            Text(translate('goodbye_message')),
          ],
        ),
      ),
    );
  }
}

在这个例子中,当用户点击按钮时,应用的语言会从英语切换到中文,并且 UI 会自动更新以显示新的翻译文本。

总结

以上代码展示了如何使用 flutter_translaty 插件在 Flutter 应用中实现国际化。你可以根据需要添加更多的语言文件,并根据应用的需求调整代码。希望这个示例对你有帮助!

回到顶部