Flutter国际化插件flutter_i18next的使用

Flutter国际化插件flutter_i18next的使用

简介

flutter_i18next 是一个为 Flutter 提供 i18next 支持的包。它基于 flutter_i18n 进行了大量修改和简化。

pub package

使用

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

    dependencies:
      flutter_i18next: ^0.3.0
    
  2. 配置本地化代理 在应用的 MaterialApp 中添加 I18NextDelegate

    import 'package:flutter/material.dart';
    import 'package:flutter_i18next/i18next.dart';
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      [@override](/user/override)
      Widget build(BuildContext context) {
        return I18NextLocaleBuilder(
          defaultLocale: Locale('en'),
          builder: (context, locale) => MaterialApp(
            title: 'Flutter Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            locale: locale,
            supportedLocales: [
              Locale('en'),
              Locale('fa'),
            ],
            home: MyHomePage(),
            localizationsDelegates: [
              I18NextDelegate(
                translationLoader: FileTranslationLoader(
                  useCountryCode: false,
                  basePath: 'assets/i18n',
                ),
                interpolationOptions:
                    InterpolationOptions(formatter: (value, format, locale) {
                  if (format == 'uppercase') {
                    return value.toString().toUpperCase();
                  }
                  return value;
                }),
              ),
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate
            ],
          ),
        );
      }
    }
    
  3. 获取翻译 可以通过 BuildContext 的扩展方法或直接使用 I18Next 类来获取翻译:

    I18Next.t(context, 'label.main')
    // 或者
    context.t('label.main')
    

访问键

你可以传递普通键或深度键,并设置默认值和回退键来检索翻译:

I18Next.t(context, 'deep.key', defaultValue: 'value', fallbackKeys: ['key1', 'key2'])

当前不支持命名空间。

插值

仅支持 i18next 的基本插值功能:

I18Next.t(context, 'key', params: {'param': 'value'})

格式化

可以提供 InterpolationOptions 实例来处理格式化:

I18NextDelegate(
  interpolationOptions:
      InterpolationOptions(formatter: (value, format, locale) {
    if (format == 'uppercase') {
      return value.toString().toUpperCase();
    } else if (value is DateTime) {
      return DateFormat(format).format(value);
    }
    return value;
  }),
)

复数形式

目前只支持单数和复数键:

I18Next.t('key', count: 2)

区间复数形式和多复数形式的语言尚未支持。

语言切换

可以使用 I18NextLocaleBuilder 来处理语言切换。首先,将应用包裹在 I18NextLocaleBuilder 中:

I18NextLocaleBuilder(
  defaultLocale: Locale('en'),
  builder: (context, locale) => MaterialApp(
    locale: locale,
    // 其他配置...
  ),
)

现在可以通过以下方式更改语言:

I18NextLocaleBuilder.of(context).locale = Locale('en');
// 或者
context.locale = Locale('en');

指定的语言应包含在应用的 supportedLocales 中,MaterialApp 会负责加载翻译并改变应用程序方向。

完整示例

以下是完整的示例代码:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_i18next/i18next.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return I18NextLocaleBuilder(
      defaultLocale: Locale('en'),
      builder: (context, locale) => MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        locale: locale,
        supportedLocales: [
          Locale('en'),
          Locale('fa'),
        ],
        home: MyHomePage(),
        localizationsDelegates: [
          I18NextDelegate(
            translationLoader: FileTranslationLoader(
              useCountryCode: false,
              basePath: 'assets/i18n',
            ),
            interpolationOptions:
                InterpolationOptions(formatter: (value, format, locale) {
              if (format == 'uppercase') {
                return value.toString().toUpperCase();
              }
              return value;
            }),
          ),
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate
        ],
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  [@override](/user/override)
  MyHomeState createState() => MyHomeState();
}

class MyHomeState extends State<MyHomePage> {
  int clicked = 0;

  void incrementCounter() {
    setState(() {
      clicked++;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('I18Next'),
        centerTitle: false,
      ),
      body: Builder(builder: (BuildContext context) {
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(I18Next.t(context, 'label.main', params: {'user': 'Test'})),
              Text(context.t('clicked.times', count: clicked)),
              TextButton(
                onPressed: () async {
                  incrementCounter();
                },
                child: Text(I18Next.t(context, 'button.label.clickMe')),
              ),
              TextButton(
                onPressed: () async {
                  context.locale = context.locale == Locale('en')
                      ? Locale('fa')
                      : Locale('en');
                },
                child: Text(I18Next.t(context, 'button.label.language')),
              ),
            ],
          ),
        );
      }),
    );
  }
}

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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用flutter_i18n(注意:flutter_i18next可能是一个打字错误,因为Flutter社区中广泛使用的国际化插件是flutter_localizations和第三方库flutter_i18n。这里我将以flutter_i18n为例进行说明)进行国际化的代码案例。

首先,确保你已经在pubspec.yaml文件中添加了flutter_i18n依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_i18n: ^0.x.x  # 请替换为最新版本号

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

1. 创建翻译文件

在你的项目根目录下创建一个assets/i18n文件夹,并在其中添加不同语言的JSON文件,例如:

  • en.json
  • zh.json

en.json内容示例:

{
  "welcome": "Welcome",
  "goodbye": "Goodbye"
}

zh.json内容示例:

{
  "welcome": "欢迎",
  "goodbye": "再见"
}

2. 配置flutter_i18n

在你的项目根目录下创建一个flutter_i18n.yaml文件,配置语言文件和默认语言:

flutter_i18n:
  enabled: true
  resource_arb_path: "assets/i18n"
  template_arb_file: "intl_en.arb"  # 这是一个模板文件,你可以根据需要创建,但不是必需的
  output_localization_file: app_localizations.dart
  use_deferred_loading: false

然后运行以下命令生成app_localizations.dart文件:

flutter pub run flutter_i18n:generate

3. 使用生成的Localizations类

在你的main.dart文件中,配置MaterialApp以支持国际化:

import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'generated/app_localizations.dart'; // 注意路径,这将是flutter_i18n生成的文件

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FlutterI18n(
      path: 'assets/i18n', // 与flutter_i18n.yaml中的resource_arb_path一致
      supportedLocales: [
        Locale('en', ''), // 英文
        Locale('zh', ''), // 中文
      ],
      fallbackLocale: Locale('en', ''), // 默认语言
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
        localizationsDelegates: [
          // 添加以下委托
          AppLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
        ],
        supportedLocales: [
          Locale('en', ''),
          Locale('zh', ''),
        ],
        locale: Locale('en'), // 初始语言
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final AppLocalizations localizations = AppLocalizations.of(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(localizations.translate('welcome')),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 切换语言示例
            FlutterI18n.refresh(context, Locale('zh'));
          },
          child: Text(localizations.translate('goodbye')),
        ),
      ),
    );
  }
}

4. 运行应用

现在,你可以运行你的Flutter应用,并通过点击按钮来切换语言,查看文本根据选择的语言进行变化。

请注意,以上代码是一个基本的示例,实际项目中可能需要根据具体需求进行调整,比如动态加载语言资源、处理复杂的语言结构等。

回到顶部