Flutter国际化插件flutter_l10n的使用

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

Flutter国际化插件flutter_l10n的使用

Pub Version (包括预发布版本)

一个用于从ARB文件生成Flutter本地化代码的Dart库。

此库是官方Flutter本地化的扩展。您可以参照此处配置flutter_l10n.yaml文件。

在线演示

特性

  • 兼容官方API。
  • 支持多个包或模块。
  • 支持不使用context

开始使用

安装/更新

dart pub global activate flutter_l10n

使用

  1. 通过运行以下命令从项目目录中的*.arb文件生成S.dart文件:

    flutterl10n
    
  2. MaterialApp/WidgetsApp中注册:

    MaterialApp(
      localizationsDelegates: [
        S.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
    );
    
  3. 通过S.of(context).helloWorldS.current.helloWorld引用字符串。

完整示例

以下是完整的示例代码,展示了如何在Flutter应用中使用flutter_l10n插件进行国际化。

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:submodule/generated/l10n.dart';

import 'generated/l10n.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter l10n',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.tealAccent),
        useMaterial3: true,
      ),
      localizationsDelegates: const [
        S.delegate,
        SubS.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: S.supportedLocales,
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

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

class _MyHomePageState extends State<MyHomePage> {
  Locale? _locale;

  [@override](/user/override)
  void didChangeDependencies() {
    super.didChangeDependencies();
    _locale = Localizations.localeOf(context);
    print(_locale?.toString());
  }

  void _changeLocale() async {
    var r = await showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              ListTile(
                title: const Text('English'),
                subtitle: const Text('en'),
                trailing: _locale?.languageCode == 'en'
                    ? const Icon(Icons.check)
                    : null,
                onTap: () {
                  _locale = const Locale('en');
                  Navigator.pop(context, true);
                },
              ),
              ListTile(
                title: const Text('简体中文'),
                subtitle: const Text('zh'),
                trailing: _locale?.languageCode == 'zh'
                    ? const Icon(Icons.check)
                    : null,
                onTap: () {
                  _locale = const Locale('zh');
                  Navigator.pop(context, true);
                },
              ),
            ],
          ),
        );
      },
    );

    if (r == true) {
      print('changed to ${_locale?.toString()}');
      setState(() {}); // 首先触发S.delegate.load(_locale)
      Future.delayed(const Duration(seconds: 1), () {
        setState(() {}); // 然后触发重建以更新S.current
      });
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Localizations.override(
      context: context,
      locale: _locale,
      child: Scaffold(
          appBar: AppBar(
            backgroundColor: Theme.of(context).colorScheme.inversePrimary,
            title: const Text('Flutter l10n'),
          ),
          body: Center(
            child: ListView(
              children: [
                ListTile(
                  title: const Text('S.current.helloWorld'),
                  subtitle: Text(S.current.helloWorld),
                ),
                ListTile(
                  title: const Text('SubS.current.helloWorld'),
                  subtitle: Text(SubS.current.helloWorld),
                ),
                ListTile(
                  title: const Text("S.current.hello('Flutter', 'Dart')"),
                  subtitle: Text(S.current.hello('Flutter', 'Dart')),
                ),
                ListTile(
                  title: const Text("S.current.helloWithAttrs('Flutter', 'Dart')"),
                  subtitle: Text(S.current.helloWithAttrs('Flutter', 'Dart')),
                ),
                ListTile(
                  title: const Text("S.current.nPandas(0)"),
                  subtitle: Text(S.current.nPandas(0)),
                ),
                ListTile(
                  title: const Text("S.current.nPandas(1)"),
                  subtitle: Text(S.current.nPandas(1)),
                ),
                ListTile(
                  title: const Text("S.current.nPandas(2)"),
                  subtitle: Text(S.current.nPandas(2)),
                ),
                ListTile(
                  title: const Text("S.current.pronoun('male')"),
                  subtitle: Text(S.current.pronoun('male')),
                ),
                ListTile(
                  title: const Text("S.current.pronoun('female')"),
                  subtitle: Text(S.current.pronoun('female')),
                ),
                ListTile(
                  title: const Text("S.current.pronoun('other')"),
                  subtitle: Text(S.current.pronoun('other')),
                ),
                ListTile(
                  title: const Text("S.current.numberOfDataPoints(12345)"),
                  subtitle: Text(S.current.numberOfDataPoints(12345)),
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              _changeLocale();
            },
            child: const Icon(Icons.change_circle),
          )),
    );
  }
}

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

1 回复

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


当然,以下是关于如何在Flutter项目中使用flutter_l10n插件进行国际化的一个详细代码示例。flutter_l10n插件是Flutter官方提供的国际化工具,支持自动生成ARB文件(Application Resource Bundle),并简化国际化流程。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加flutter_localizationsflutter_gen_runner的依赖。

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

dev_dependencies:
  flutter_gen_runner: ^4.0.0  # 确保版本与Flutter兼容
  build_runner: ^2.0.0

2. 配置flutter_gen

pubspec.yaml中,添加flutter_gen配置来生成ARB文件:

flutter_gen:
  output: lib/l10n/  # 生成的ARB文件存放路径
  arb_dir: lib/l10n/arb/  # ARB文件模板存放路径
  template_arb_file: messages.arb  # ARB文件模板名称
  languages:  # 支持的语言列表
    - en  # 英文
    - zh  # 中文

3. 创建ARB模板文件

lib/l10n/arb/目录下创建messages.arb文件,并添加一些示例翻译内容:

{
  "@@locale": "en",
  "greeting": "Hello, {name}!",
  "farewell": "Goodbye, {name}."
}

创建中文翻译文件messages_zh.arb

{
  "@@locale": "zh",
  "greeting": "你好,{name}!",
  "farewell": "再见,{name}。"
}

4. 生成ARB文件和本地化资源

在终端中运行以下命令生成ARB文件和本地化资源:

flutter gen-l10n

这会在lib/l10n/目录下生成l10n.dart文件,并包含所有语言的翻译。

5. 在应用中使用本地化资源

lib/main.dart文件中,使用生成的本地化资源:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'l10n/l10n.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      localizationsDelegates: [
        AppLocalizations.delegate,  // 添加本地化委托
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: AppLocalizations.supportedLocales,  // 支持的语言列表
      home: MyHomePage(),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    final localizations = AppLocalizations.of(context)!;  // 获取本地化实例

    return Scaffold(
      appBar: AppBar(
        title: Text(localizations.greeting('World')),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              localizations.greeting('Flutter'),
            ),
            Text(
              localizations.farewell('Flutter'),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 切换语言示例(例如,从英语切换到中文)
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => LocaleChanger(locale: Locale('zh')),
            ),
          );
        },
        tooltip: 'Change Locale',
        child: Icon(Icons.translate),
      ),
    );
  }
}

class LocaleChanger extends StatelessWidget {
  final Locale locale;

  LocaleChanger({required this.locale});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Locale Changer'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              Navigator.popAndPushNamed(context, '/');
              // 应用新的locale
              Localizations.override(
                context,
                Localizations(
                  locale: locale,
                  resources: Localizations.resourcesFor(context).copyWith(locale: locale),
                ),
                () {},
              );
            },
            child: Text('Apply Locale'),
          ),
        ),
      ),
      locale: locale,
      localizationsDelegates: [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: AppLocalizations.supportedLocales,
    );
  }
}

6. 运行应用

现在,你可以运行你的Flutter应用,并看到根据设备语言设置显示的翻译内容。你也可以通过点击浮动操作按钮(FAB)来手动切换语言。

这个示例展示了如何使用flutter_l10n插件进行Flutter应用的国际化。通过ARB文件和flutter gen-l10n命令,你可以轻松管理和更新应用的翻译内容。

回到顶部