Flutter国际化插件gen_i18n的使用

Flutter国际化插件 gen_i18n 的使用

简介

gen_i18n 是一个用于在 Dart 项目中添加国际化支持的插件。通过这个插件,你可以轻松地管理多语言翻译文件,并在应用中动态切换语言。

安装

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

dependencies:
    flutter_localizations:
        sdk: flutter 

dev_dependencies:
    gen_i18n: ^1.0.3

flutter: 
  assets:
    - assets/i18n/locale/

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

使用

初始化

运行以下命令来初始化插件并生成必要的文件:

flutter pub run gen_i18n:initialize

这将生成以下文件:

  • i18n.dart: 这是一个位于 lib/i18n/ 目录下的 Dart 文件,负责解析翻译文件。
  • locale: 翻译文件所在的目录,默认路径为 assets/i18n/locale

注意: 翻译文件的命名应以 i18n_ 开头,例如 i18n_en.json

支持参数

你可以在初始化时指定多个语言环境:

flutter pub run gen_i18n:initialize --locale=pt --locale=es

示例代码

项目结构

假设你的项目结构如下:

project_root/
├── assets/
│   └── i18n/
│       └── locale/
│           ├── i18n_en.json
│           └── i18n_pt.json
├── lib/
│   ├── main.dart
│   └── i18n/
│       └── i18n.dart
└── pubspec.yaml

i18n_en.json 示例

{
  "customMessage": "Write is here your message"
}

i18n_pt.json 示例

{
  "customMessage": "Escreva sua mensagem aqui"
}

修改 main.dart

main.dart 中进行以下修改:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:your_project_name/i18n/i18n.dart';

const _supportLocales = [Locale('en'), Locale('pt')];

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

  await I18n.initialize(
      defaultLocale: Locale('en'),
      supportLocales: _supportLocales,
  );

  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      locale: I18n.currentLocate,
      supportedLocales: I18n.supportedLocales,
      localizationsDelegates: const [
        I18nDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  Locale _locale = Locale('en');

  void onChanged(Locale? locale) async {
    if (locale == null) return;
    await I18n.updateLocate(locale);
    setState(() => _locale = locale);
  }

  DropdownMenuItem<Locale> _itemBuild(Locale item) {
    return DropdownMenuItem<Locale>(
      child: Text(item.toLanguageTag()),
      value: item,
    );
  }

  Widget _languageBody() {
    return DropdownButton<Locale>(
      value: _locale,
      items: _supportLocales.map(_itemBuild).toList(),
      onChanged: onChanged,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'customMessage'.translate,
            ),
            _languageBody()
          ],
        ),
      ),
    );
  }
}

切换语言

你可以通过调用 I18n.updateLocate(Locale('es')) 方法来动态切换当前的语言环境。

显示翻译文本

要显示翻译后的文本,可以使用以下两种方法之一:

Text(I18n.getValue('customMessage'))
// 或者
Text('customMessage'.translate)

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

1 回复

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


当然,以下是一个关于如何使用Flutter国际化插件gen_i18n的示例代码案例。这个插件可以帮助你更高效地管理应用的国际化资源。

1. 添加依赖

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

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

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

2. 创建翻译文件

在项目的assets目录下创建一个locales文件夹,并在其中创建不同语言的翻译文件。例如:

  • locales/en.json
  • locales/zh.json

en.json文件内容示例:

{
  "greeting": "Hello",
  "farewell": "Goodbye"
}

zh.json文件内容示例:

{
  "greeting": "你好",
  "farewell": "再见"
}

3. 配置pubspec.yaml

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

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

4. 使用gen_i18n生成代码

创建一个新的Dart文件(例如i18n.dart),并在其中使用gen_i18n提供的工具生成翻译类。你可以手动编写或使用命令行工具自动生成。以下是手动编写的示例:

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

// 定义国际化委托类
class AppLocalizations {
  static Future<AppLocalizations> load(Locale locale) async {
    final String name = locale.toString().split('_').first;
    final String jsonString = await rootBundle.loadString("assets/locales/$name.json");
    final Map<String, dynamic> jsonMap = jsonDecode(jsonString);
    
    AppLocalizations localizations = AppLocalizations();
    localizations.locale = locale;
    localizations.t = (key, args) => Intl.message(jsonMap[key] ?? key, args);
    
    return localizations;
  }

  Locale locale;
  Intl.MessageLookupFunction t;
}

// 使用Intl库进行消息查找
@pragma('vm:entry-point')
class Intl {
  static MessageLookupFunction messageLookupFunction = null;

  static String message(String key, Map<String, dynamic> args) {
    if (messageLookupFunction == null) return key;
    return messageLookupFunction(key, args);
  }
}

typedef MessageLookupFunction = String Function(String key, Map<String, dynamic> args);

5. 在应用中使用国际化

在你的MaterialApp中设置localizationsDelegatessupportedLocales

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      supportedLocales: [
        Locale('en', ''),
        Locale('zh', ''),
      ],
      localizationsDelegates: [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final AppLocalizations localizations = Localizations.localeOf(context).localizations.cast<AppLocalizations>();
    return Scaffold(
      appBar: AppBar(
        title: Text(localizations.t('greeting')!),
      ),
      body: Center(
        child: Text(localizations.t('farewell')!),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 示例:切换语言
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => LanguageSelector()),
          );
        },
        tooltip: 'Pick a language',
        child: Icon(Icons.translate),
      ),
    );
  }
}

class LanguageSelector extends StatefulWidget {
  @override
  _LanguageSelectorState createState() => _LanguageSelectorState();
}

class _LanguageSelectorState extends State<LanguageSelector> {
  List<Locale> locales = [
    Locale('en', ''),
    Locale('zh', ''),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Select Language'),
      ),
      body: ListView.builder(
        itemCount: locales.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(locales[index].toString()),
            onTap: () {
              Navigator.popAndPushNamed(context, '/', arguments: locales[index]);
            },
          );
        },
      ),
    );
  }
}

在上面的代码中,LanguageSelector页面允许用户选择不同的语言,并通过Navigator.popAndPushNamed重新加载主页面并应用新的语言设置。

请注意,上面的代码是一个基础示例,你可能需要根据实际需要进行调整和扩展。

回到顶部