Flutter国际化插件blizzard_intl的使用

Flutter国际化插件blizzard_intl的使用

Blizzard Intl 提供了一种方便的方法来实现 Flutter 应用程序的国际化,通过提供一组与文本相关的部件,这些部件接受 Map<T, String> 类型的数据而不是 String 类型,允许你传递多语言翻译而不是单一语言文本。

基本设置

  1. 创建一个枚举来表示支持的语言。
  2. 可选:为每种语言创建别名。
  3. 可选:为语言映射创建一个类型别名。
  4. 将应用包装在 LanguageWrapper 中,并设置默认语言。

步骤 1

创建一个枚举来表示应用程序支持的语言。

enum Language {
  english,
  german,
}

步骤 2(可选)

建议为每个语言枚举值创建缩写形式的别名。

const de = Language.german;
const en = Language.english;

步骤 3(可选)

建议为语言映射创建一个类型别名。

typedef Translation = Map<Language, String>;

步骤 4

将应用包装在 LanguageWrapper 中,并设置默认语言。可以选择设置选定语言。

LanguageWrapper<Language>(
  defaultLanguage: en,
  child: MaterialApp(
    home: Scaffold(
      appBar: AppBar(
        title: const intl.Text({
          de: 'Meine App',
          en: 'My App',
        }),
      ),
    ),
  ),
);

注意:如果 selectedLanguagenull,则会使用 defaultLanguage 作为文本部件的默认语言。如果选定语言缺少翻译,则会使用默认语言的翻译。

完整示例

import 'package:blizzard_intl/blizzard_intl.dart' as intl;
import 'package:flutter/material.dart';

enum Language {
  english,
  german,
}

const de = Language.german;
const en = Language.english;

typedef Translation = Map<Language, String>;

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

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

  @override
  Widget build(BuildContext context) {
    return intl.LanguageWrapper<Language>(
      defaultLanguage: en,
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: const intl.Text({
              de: 'Meine App',
              en: 'My App',
            }),
          ),
        ),
      ),
    );
  }
}

获取语言

可以通过 LanguageManager 获取默认或选定的语言。

final defaultLanguage = LanguageManager.of<Language>(context).defaultLanguage;
final selectedLanguage = LanguageManager.of<Language>(context).selectedLanguage;

注意:通常不需要这样做,因为提供的文本部件会在底层处理这个问题。

选择语言

可以通过调用 LanguageManageronLanguageSelected 方法来选择语言。

LanguageManager.of<Language>(context).onLanguageSelected(de);

分离关注点

鉴于 Blizzard Intl 更加注重行为的局部性(LoB),建议将翻译分为本地翻译和全局翻译,优先使用本地翻译,只有必要时才提升到全局翻译。

本地翻译

本地翻译直接在文本应出现的部件上定义翻译。

class ConfirmButton extends StatelessWidget {
  const ConfirmButton();

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: () {},
      child: intl.Text({
        de: 'Bestätigen',
        en: 'Confirm',
      }),
    );
  }
}

全局翻译

全局翻译在全局文件中定义翻译,然后在本地导入。

translations.dart

const Translation confirmText = {
  de: 'Bestätigen',
  en: 'Confirm',
};

confirm_button.dart

import 'package:blizzard_intl/blizzard_intl.dart' as intl;
import 'package:flutter/material.dart';

import 'translations.dart' as translations;

class ConfirmButton extends StatelessWidget {
  const ConfirmButton();

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: () {},
      child: intl.Text(translations.confirmText),
    );
  }
}

导入冲突

Blizzard Intl 提供的文本部件在命名和参数方面与 Flutter 的等效部件完全相同。这意味着它们的功能完全相同,唯一的区别是任何 String 参数应该替换为 Map<T, String>。这包括 semanticsLabel

在某些情况下,提供多个翻译可能是不必要的,例如在向用户显示计数器时。因此,Blizzard Intl 并不会使 Flutter 的基于 String 的部件过时。

建议对 Blizzard Intl 使用限定导入,如下所示:

import 'package:blizzard_intl/blizzard_intl.dart' as intl;

对于很少使用单语言文本的项目,可以创建一个预导入文件,如 prelude.dart,导出所需的默认值,然后在使用单语言文本时使用限定导入,如下所示:

prelude.dart

export 'package:blizzard_intl/blizzard_intl.dart';
export 'package:flutter/material.dart'
    hide InlineSpan, RichText, Text, TextSpan, WidgetSpan;

my_app.dart

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

import 'prelude.dart';

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

1 回复

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


当然,关于Flutter国际化插件blizzard_intl的使用,下面是一个具体的代码案例,展示如何设置和使用该插件进行应用的国际化。

1. 添加依赖

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

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

然后运行flutter pub get来安装依赖。

2. 创建intl文件

在项目的根目录下创建一个名为intl的文件夹,并在其中创建多个语言文件,例如messages_en.arbmessages_zh.arb

messages_en.arb:

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

messages_zh.arb:

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

3. 生成本地化文件

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

flutter pub run blizzard_intl:generate

这个命令会生成一个l10n文件夹,其中包含用于Flutter应用的本地化资源。

4. 设置MaterialApp的localizationsDelegates和supportedLocales

在你的main.dart文件中,设置MaterialApplocalizationsDelegatessupportedLocales属性:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'generated/l10n.dart'; // 注意这里是生成的l10n文件

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      localizationsDelegates: [
        S.delegate, // 添加生成的delegate
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: S.delegate.supportedLocales, // 添加支持的locales
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final S localizations = S.of(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(localizations.welcomeMessage),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(localizations.welcomeMessage),
            ElevatedButton(
              onPressed: () {
                // 示例:切换语言(这里只是演示,实际应用中可能需要更复杂的逻辑)
                // 注意:这里只是模拟切换语言,实际切换语言通常需要更复杂的逻辑,比如保存用户偏好设置
                if (Localizations.localeOf(context).languageCode == 'en') {
                  Navigator.pushAndRemoveUntil(
                    context,
                    MaterialPageRoute(builder: (context) => MyApp(locale: Locale('zh'))),
                    (route) => false,
                  );
                } else {
                  Navigator.pushAndRemoveUntil(
                    context,
                    MaterialPageRoute(builder: (context) => MyApp(locale: Locale('en'))),
                    (route) => false,
                  );
                }
              },
              child: Text(localizations.goodbyeMessage),
            ),
          ],
        ),
      ),
    );
  }
}

注意:上面的代码示例中,直接通过Navigator来切换语言是一个简化的例子。在实际应用中,你可能需要更复杂的逻辑来持久化用户的语言偏好设置,并在应用启动时根据这些设置来设置语言环境。

5. 运行应用

现在,你可以运行你的Flutter应用,并根据设备的语言设置或按钮点击来查看不同语言的文本。

以上代码展示了如何使用blizzard_intl插件来实现Flutter应用的国际化。希望这对你有所帮助!

回到顶部