Flutter本地化支持插件flutter_localization的使用

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

Flutter本地化支持插件flutter_localization的使用

Flutter Localization 是一个用于应用内本地化的包,它使用Map数据进行本地化。这个包的灵感来自于Flutter SDK 的 flutter_localizations 库。以下是该包的使用指南。

使用步骤

准备语言源(Map<String, dynamic>)

创建一个包含所有需要的本地语言Map数据的dart文件。你可以根据需要更改文件名、类名和文件路径。例如:

mixin AppLocale {
  static const String title = 'title';

  static const Map<String, dynamic> EN = {title: 'Localization'};
  static const Map<String, dynamic> KM = {title: 'ការធ្វើមូលដ្ឋានីយកម្ម'};
  static const Map<String, dynamic> JA = {title: 'ローカリゼーション'};
}

项目配置

  1. 确保插件初始化:更新main函数为异步函数,并在runApp()函数之前添加WidgetsFlutterBinding.ensureInitialized()await FlutterLocalization.instance.ensureInitialized()

    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await FlutterLocalization.instance.ensureInitialized();
      runApp(const MyApp());
    }
    
  2. 初始化FlutterLocalization对象:可以是局部或全局变量,取决于你的需求。

    final FlutterLocalization localization = FlutterLocalization.instance;
    
  3. 初始化MapLocale列表和启动语言:这必须在main.dart或项目的MaterialApp中完成。

    [@override](/user/override)
    void initState() {
      localization.init(
        mapLocales: [
          const MapLocale('en', AppLocale.EN),
          const MapLocale('km', AppLocale.KM),
          const MapLocale('ja', AppLocale.JA),
        ],
        initLanguageCode: 'en',
      );
      localization.onTranslatedLanguage = _onTranslatedLanguage;
      super.initState();
    }
    
    // 必须添加setState函数
    void _onTranslatedLanguage(Locale? locale) {
      setState(() {});
    }
    
  4. 添加supportedLocales和localizationsDelegates到MaterialApp

    [@override](/user/override)
    Widget build(BuildContext context) {
      return MaterialApp(
        supportedLocales: localization.supportedLocales,
        localizationsDelegates: localization.localizationsDelegates,
        home: const SettingsScreen(),
      );
    }
    
  5. 调用translate函数以翻译应用程序

    ElevatedButton(
      child: const Text('English'),
      onPressed: () {
        localization.translate('en');
      },
    );
    
  6. 显示Map数据中的值

    AppLocale.title.getString(context);
    

额外功能

  • 获取语言名称:如果你不指定语言代码,则返回当前应用程序区域设置的语言名称。

    localization.getLanguageName(languageCode: 'en');  // English
    localization.getLanguageName(languageCode: 'km');  // ភាសាខ្មែរ
    localization.getLanguageName(languageCode: 'ja');  // 日本語
    
    localization.getLanguageName();  // 获取当前应用程序区域设置的语言名称
    
  • 获取locale标识符:格式为languageCode_scriptCode_countryCodescriptCodecountryCode是可选的。

    localization.currentLocale.localeIdentifier;
    

更新说明

版本0.3.0

从版本0.3.0开始,初始化流程发生了重大变化。请重新检查README文档中的“项目配置”部分以了解更多详情。主要变化包括:

  • main函数从void更改为Future以支持ensureInitialized函数。
  • 调用ensureInitialized函数以初始化包的核心功能。

版本0.1.13

添加了Strings UtilContext Extension,用于帮助处理基于语言的动态本地化文本。具体用法参见示例

版本0.1.11

可以在init()函数中的MapLocale模型中提供字体系列,字体可以从AssetsGoogleFonts包中获取。

// 字体系列来自资源
MapLocale('en', AppLocale.EN, fontFamily: 'MuseoSans');

// 或者来自GoogleFonts包
MapLocale('en', AppLocale.EN, fontFamily: GoogleFonts.lato().fontFamily);

最后,将字体系列提供给MaterialApp的ThemeData。

[@override](/user/override)
Widget build(BuildContext context) {
  return MaterialApp(
    supportedLocales: localization.supportedLocales,
    localizationsDelegates: localization.localizationsDelegates,
    home: const SettingsScreen(),
    theme: ThemeData(fontFamily: localization.fontFamily),
  );
}

示例代码

以下是一个完整的示例demo,展示了如何使用flutter_localization插件进行本地化。

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

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

mixin AppLocale {
  static const String title = 'title';
  static const String thisIs = 'thisIs';

  static const Map<String, dynamic> EN = {
    title: 'Localization',
    thisIs: 'This is %a package, version %a.',
  };
  static const Map<String, dynamic> KM = {
    title: 'ការធ្វើមូលដ្ឋានីយកម្ម',
    thisIs: 'នេះគឺជាកញ្ចប់%a កំណែ%a.',
  };
  static const Map<String, dynamic> JA = {
    title: 'ローカリゼーション',
    thisIs: 'これは%aパッケージ、バージョン%aです。',
  };
}

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final FlutterLocalization _localization = FlutterLocalization.instance;

  [@override](/user/override)
  void initState() {
    _localization.init(
      mapLocales: [
        const MapLocale(
          'en',
          AppLocale.EN,
          countryCode: 'US',
          fontFamily: 'Font EN',
        ),
        const MapLocale(
          'km',
          AppLocale.KM,
          countryCode: 'KH',
          fontFamily: 'Font KM',
        ),
        const MapLocale(
          'ja',
          AppLocale.JA,
          countryCode: 'JP',
          fontFamily: 'Font JA',
        ),
      ],
      initLanguageCode: 'en',
    );
    _localization.onTranslatedLanguage = _onTranslatedLanguage;
    super.initState();
  }

  void _onTranslatedLanguage(Locale? locale) {
    setState(() {});
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      supportedLocales: _localization.supportedLocales,
      localizationsDelegates: _localization.localizationsDelegates,
      home: const SettingsScreen(),
      theme: ThemeData(fontFamily: _localization.fontFamily),
    );
  }
}

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

  [@override](/user/override)
  State<SettingsScreen> createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {
  final FlutterLocalization _localization = FlutterLocalization.instance;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(AppLocale.title.getString(context))),
      body: Container(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                    child: const Text('English'),
                    onPressed: () {
                      _localization.translate('en');
                    },
                  ),
                ),
                const SizedBox(width: 16.0),
                Expanded(
                  child: ElevatedButton(
                    child: const Text('ភាសាខ្មែរ'),
                    onPressed: () {
                      _localization.translate('km');
                    },
                  ),
                ),
                const SizedBox(width: 16.0),
                Expanded(
                  child: ElevatedButton(
                    child: const Text('日本語'),
                    onPressed: () {
                      _localization.translate('ja', save: false);
                    },
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16.0),
            ItemWidget(
              title: 'Current Language',
              content: _localization.getLanguageName(),
            ),
            ItemWidget(
              title: 'Font Family',
              content: _localization.fontFamily,
            ),
            ItemWidget(
              title: 'Locale Identifier',
              content: _localization.currentLocale.localeIdentifier,
            ),
            ItemWidget(
              title: 'String Format',
              content: Strings.format(
                'Hello %a, this is me %a.',
                ['Dara', 'Sopheak'],
              ),
            ),
            ItemWidget(
              title: 'Context Format String',
              content: context.formatString(
                AppLocale.thisIs,
                [AppLocale.title, 'LATEST'],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ItemWidget extends StatelessWidget {
  const ItemWidget({
    super.key,
    required this.title,
    required this.content,
  });

  final String? title;
  final String? content;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 8.0),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Expanded(child: Text(title ?? '')),
          const Text(' : '),
          Expanded(child: Text(content ?? '')),
        ],
      ),
    );
  }
}

通过以上步骤和示例代码,你可以轻松地在Flutter项目中实现多语言支持。希望这些信息对你有所帮助!


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

1 回复

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


在Flutter中,flutter_localization 插件用于支持应用的本地化。这个插件允许你为应用提供多语言支持,并且能根据用户的设备语言设置自动切换语言。下面是一个完整的示例,展示如何使用 flutter_localization 插件进行本地化支持。

1. 添加依赖

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

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

2. 创建本地化文件

接下来,你需要为每种支持的语言创建ARB(Application Resource Bundle)文件。例如,创建 messages_en.arbmessages_zh.arb 文件:

messages_en.arb

{
  "welcome_message": "Welcome to Flutter!"
}

messages_zh.arb

{
  "welcome_message": "欢迎来到Flutter!"
}

将这些ARB文件放在项目的 lib/l10n 目录下。

3. 生成本地化代码

Flutter 提供了一个工具来从ARB文件生成Dart代码。你可以使用以下命令来生成代码:

flutter pub run flutter_gen:generate

确保你的项目根目录下有一个 flutter_gen 配置文件,例如 flutter_gen.yaml,用于指定ARB文件的路径:

l10n:
  path: "lib/l10n"

4. 设置MaterialApp的localizationsDelegates和supportedLocales

在你的主文件(通常是 main.dart)中,设置 MaterialApplocalizationsDelegatessupportedLocales 属性:

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.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,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: AppLocalizations.supportedLocales,
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final AppLocalizations localizations = AppLocalizations.of(context)!;
    return Scaffold(
      appBar: AppBar(
        title: Text(localizations.welcomeMessage),
      ),
      body: Center(
        child: Text(localizations.welcomeMessage),
      ),
    );
  }
}

5. 运行应用

现在,你可以运行你的应用,并根据设备的语言设置查看不同的本地化内容。如果你的设备语言设置为英语,你将看到 “Welcome to Flutter!”;如果设置为中文,你将看到 “欢迎来到Flutter!”。

总结

通过上述步骤,你已经成功在Flutter应用中使用 flutter_localization 插件实现了本地化支持。这包括添加依赖、创建ARB文件、生成本地化代码以及配置 MaterialApp。这种方法使得管理多语言内容变得简单且高效。

回到顶部