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

发布于 1周前 作者 yibo5220 来自 Flutter

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

简介

intl_translation 是一个用于从程序源代码中提取需要翻译的消息并生成翻译后的代码的工具。它与 intl 包配合使用,帮助开发者实现应用程序的国际化和本地化。intl_translation 是一个独立的包,因此不会为所有用户引入对 analyzer 的依赖。

提取和使用翻译消息

当你的程序中包含需要翻译的消息时,这些消息必须从程序源代码中提取出来,发送给翻译人员进行翻译,然后将翻译结果整合到程序中。

提取消息

要提取消息,可以运行 extract_to_arb.dart 程序。以下是一个示例命令:

dart run intl_translation:extract_to_arb --output-dir=target/directory \
    my_program.dart more_of_my_program.dart

你可以使用通配符来提取多个文件中的消息。例如,要从路径 lib/**/*.dart 中的所有 Dart 文件提取消息,可以运行以下命令:

dart run intl_translation:extract_to_arb --output-dir=target/directory \
    lib/**/*.dart

这将生成一个名为 intl_messages.arb 的文件,其中包含所有这些程序中的消息。ARB(Application Resource Bundle)格式文件可以用于输入到翻译工具中,如 Localizely 或 Lyrebird。

生成翻译后的代码

翻译完成后,可以使用 generate_from_arb.dart 程序生成一组库文件,每个库文件对应一个语言环境。以下是一个示例命令:

dart run intl_translation:generate_from_arb --generated-file-prefix=<prefix> \
    <my_dart_files> <translated_ARB_files>

这将生成一系列 Dart 库文件,每个文件对应一个语言环境,包含翻译后的版本。你的 Dart 库可以导入主文件,命名为 <prefix>messages_all.dart,然后调用特定语言环境的初始化函数。一旦初始化完成,任何 Intl.message 调用都会自动打印翻译后的版本,而不是原始版本。

以下是一个示例代码片段,展示了如何在 Dart 代码中使用这些生成的库:

import 'my_prefix_messages_all.dart';

void main() async {
  // 初始化特定语言环境的消息
  await initializeMessages('zh_CN');

  // 打印一些消息
  printSomeMessages();
}

void printSomeMessages() {
  // 使用 Intl.message 打印翻译后的消息
  print(Intl.message('Hello, world!', name: 'helloWorld'));
}

示例项目

为了更好地理解 intl_translation 的使用,我们可以通过一个示例项目来演示其工作流程。

示例项目结构

假设我们有一个简单的 Flutter 项目,包含以下文件结构:

.
├── lib
│   ├── main.dart
│   └── messages_all.dart
├── target
│   └── directory
│       └── intl_messages.arb
└── pubspec.yaml

步骤 1:添加依赖

首先,在 pubspec.yaml 文件中添加 intlintl_translation 依赖:

dependencies:
  flutter:
    sdk: flutter
  intl: ^0.17.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  intl_translation: ^0.18.0

步骤 2:编写需要翻译的消息

lib/main.dart 中编写一些需要翻译的消息:

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'messages_all.dart';

void main() async {
  // 初始化特定语言环境的消息
  await initializeMessages('zh_CN');

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(Intl.message('Welcome to Flutter', name: 'welcomeMessage')),
      ),
      body: Center(
        child: Text(Intl.message('Hello, world!', name: 'helloWorld')),
      ),
    );
  }
}

步骤 3:提取消息

在项目根目录下运行以下命令,将需要翻译的消息提取到 target/directory/intl_messages.arb 文件中:

dart run intl_translation:extract_to_arb --output-dir=target/directory \
    lib/main.dart

步骤 4:翻译消息

打开 target/directory/intl_messages.arb 文件,将其内容翻译成目标语言。例如,将英文翻译成中文:

{
  "helloWorld": "你好,世界!",
  "welcomeMessage": "欢迎来到 Flutter",
  "@helloWorld": {
    "description": "A simple greeting message"
  },
  "@welcomeMessage": {
    "description": "A welcome message for the app"
  }
}

步骤 5:生成翻译后的代码

保存翻译后的 intl_messages.arb 文件,并运行以下命令生成翻译后的 Dart 代码:

dart run intl_translation:generate_from_arb --generated-file-prefix=messages \
    lib/main.dart target/directory/intl_messages.arb

这将在 lib/generated 目录下生成一系列文件,例如 messages_zh_CN.dart,其中包含翻译后的消息。

步骤 6:运行应用

现在,你可以运行你的 Flutter 应用,它将显示翻译后的消息:

flutter run

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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用intl_translation插件进行国际化翻译的详细代码示例。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加intlflutter_localizations依赖:

dependencies:
  flutter:
    sdk: flutter
  intl: ^0.17.0 # 请检查最新版本

dev_dependencies:
  flutter_test:
    sdk: flutter
  intl_translation: ^0.17.10+1 # 请检查最新版本

2. 创建arb文件

lib/l10n目录下创建一个ARB(Application Resource Bundle)文件,例如messages_en.arbmessages_zh.arb。ARB文件用于定义不同语言的翻译内容。

messages_en.arb

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

messages_zh.arb

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

3. 生成本地化文件

在项目根目录下创建一个名为tool的目录,并在其中创建一个generate_localizations.dart脚本,用于生成本地化文件。

generate_localizations.dart

import 'package:intl_translation/generate_localized.dart';

void main() {
  generateLocalizedFiles(
    templateArbFile: 'lib/l10n/messages_en.arb',
    outputDirectory: 'lib/l10n/generated',
    arbDir: 'lib/l10n',
    mainDartFile: 'lib/main.dart',
    className: 'S', // 这是生成的Localizations类的名称前缀
    useDeferredLoading: true,
  );
}

pubspec.yaml中,添加一个运行脚本:

scripts:
  generate_localizations: dart tool/generate_localizations.dart

运行以下命令生成本地化文件:

flutter pub run script:generate_localizations

4. 使用生成的本地化文件

lib/main.dart中,导入生成的本地化文件并使用它们。

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'l10n/messages_all.dart'; // 自动生成的本地化文件

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Intl Example',
      localizationsDelegates: [
        S.delegate, // 使用生成的LocalizationsDelegate
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: S.delegate.supportedLocales, // 支持的语言列表
      home: MyHomePage(),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  Locale _locale;

  @override
  Widget build(BuildContext context) {
    _locale = Localizations.localeOf(context);
    final S _local = S.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(_local.welcome_message),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(_local.welcome_message),
            ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => ChangeLocaleScreen(),
                  ),
                );
              },
              child: Text('Change Locale'),
            ),
          ],
        ),
      ),
    );
  }
}

class ChangeLocaleScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Change Locale'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () {
                Navigator.popAndPushNamed(context, '/', arguments: Locale('en', ''));
              },
              child: Text('English'),
            ),
            ElevatedButton(
              onPressed: () {
                Navigator.popAndPushNamed(context, '/', arguments: Locale('zh', ''));
              },
              child: Text('中文'),
            ),
          ],
        ),
      ),
    );
  }
}

在上面的代码中,我们通过Navigator.popAndPushNamed方法来改变应用的当前语言环境。注意,这里我们假设根路由/MyHomePage

5. 更新路由处理

确保在MaterialApp中处理路由参数以更新语言环境:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Intl Example',
      localizationsDelegates: [
        S.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: S.delegate.supportedLocales,
      onGenerateRoute: (RouteSettings settings) {
        Locale locale = settings.arguments is Locale ? settings.arguments as Locale : Locale('en', '');
        return MaterialPageRoute<void>(
          settings: settings.copyWith(arguments: locale),
          builder: (BuildContext context) {
            return Localizations(
              locale: locale,
              child: MyHomePage(),
            );
          },
        );
      },
      initialRoute: '/',
      routes: {
        '/': (context) => MyHomePage(),
      },
    );
  }
}

注意,这里的路由处理逻辑仅作为示例,实际项目中可能需要更复杂的处理逻辑。

这样,你就完成了在Flutter项目中使用intl_translation插件进行国际化翻译的基本设置。

回到顶部