Flutter国际化插件internationalization的使用

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

Flutter国际化插件internationalization的使用

概述

internationalization 是一个用于轻松实现Flutter项目国际化的插件。它支持多种语言和区域设置,并且可以方便地加载外部JSON文件进行翻译。

基本使用

MaterialApp 配置

在你的MaterialApp中配置支持的语言和地区,以及本地化代理:

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

final List<Locale> _supportedLocales = [
  Locale('en', ''),
  Locale('pt', ''),
];

final String _translationsPath = './assets/strings/';

MaterialApp(
  supportedLocales: _supportedLocales,
  localizationsDelegates: [
    InternationalizationDelegate(
      translationsPath: _translationsPath,
      suportedLocales: _supportedLocales,
      addTranslations: (locale) async {
        // 这里可以从外部获取JSON并添加到国际化中。
        // 注意:JSON必须遵循与assets相同的结构。
        return {
          'external_translate': 'Translation from external source',
        };
      },      
    ),
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
);

pubspec.yaml中暴露JSON文件夹

确保在pubspec.yaml中正确配置资源路径:

flutter:
  uses-material-design: true
  assets:
    - ./assets/strings/en/
    - ./assets/strings/pt/

文件夹结构

请按照以下结构创建文件夹,确保与pubspec.yaml中的配置一致:

Folder Structure

翻译示例

简单字符串翻译

"simple_string".translate(context, translationContext: _translationContext),
context.translate('interpolation_string', translationContext: _translationContext, args: ["( ͡° ͜ʖ ͡°)"]),
context.translate('interpolation_string_with_named_args', translationContext: _translationContext, namedArgs: {"named_arg_key": "( ͡° ͜ʖ ͡°)"}),

复数形式翻译

context.translate('simple_plurals', translationContext: _translationContext, pluralValue: 0),
context.translate('simple_plurals', translationContext: _translationContext, pluralValue: 1),
context.translate('simple_plurals', translationContext: _translationContext, pluralValue: 123456789),

插值复数形式翻译

context.translate('interpolation_plurals', translationContext: _translationContext, pluralValue: 0, args: ["( ͡° ͜ʖ ͡°)"]),
context.translate('interpolation_plurals', translationContext: _translationContext, pluralValue: 1, args: ["( ͡° ͜ʖ ͡°)"]),
context.translate('interpolation_plurals', translationContext: _translationContext, pluralValue: 123456789, args: ["123456789"]),

NumberFormat & DateFormat

这些功能来自intl库,已经被集成到Internationalization中:

完整示例Demo

下面是一个完整的示例项目,展示如何使用internationalization插件:

pubspec.yaml

name: internationalization_demo
description: A demo for internationalization in Flutter.

dependencies:
  flutter:
    sdk: flutter
  internationalization: ^latest_version # 替换为最新版本号

flutter:
  uses-material-design: true
  assets:
    - ./assets/strings/en/
    - ./assets/strings/pt/

lib/main.dart

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

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

class MyApp extends StatelessWidget {
  final List<Locale> _supportedLocales = [
    Locale('en', ''),
    Locale('pt', ''),
  ];

  final String _translationsPath = './assets/strings/';

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Internationalization Demo',
      supportedLocales: _supportedLocales,
      localizationsDelegates: [
        InternationalizationDelegate(
          translationsPath: _translationsPath,
          suportedLocales: _supportedLocales,
          addTranslations: (locale) async {
            return {
              'external_translate': 'Translation from external source',
            };
          },      
        ),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Internationalization Demo"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text("simple_string".translate(context)),
            Text(context.translate('interpolation_string', args: ["( ͡° ͜ʖ ͡°)"])),
            Text(context.translate('interpolation_string_with_named_args', namedArgs: {"named_arg_key": "( ͡° ͜ʖ ͡°)"})),
            Text(context.translate('simple_plurals', pluralValue: 0)),
            Text(context.translate('simple_plurals', pluralValue: 1)),
            Text(context.translate('simple_plurals', pluralValue: 123456789)),
          ],
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是关于如何在Flutter中使用flutter_localizations包和intl包来实现国际化的一个详细代码示例。这将包括设置本地化文件、配置应用程序以及动态切换语言的功能。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0  # 确保使用最新版本

2. 创建本地化文件

在你的项目根目录下创建一个assets文件夹,然后在其中创建一个locales文件夹。在locales文件夹中,为每个支持的语言创建相应的ARB(Application Resource Bundle)文件。例如,为英语和中文创建以下文件:

  • assets/locales/en.arb
  • assets/locales/zh.arb

en.arb文件内容示例:

{
  "welcome_message": "Welcome!",
  "goodbye_message": "Goodbye!"
}

zh.arb文件内容示例:

{
  "welcome_message": "欢迎!",
  "goodbye_message": "再见!"
}

3. 配置应用程序

lib目录下创建一个l10n文件夹,并在其中创建一个messages.dart文件来加载ARB文件。同时,确保在MaterialApp中配置LocalizationsDelegatesupportedLocales

lib/l10n/messages.dart

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'dart:convert';
import 'package:flutter/services.dart' show rootBundle;

class AppLocalizations {
  AppLocalizations(this.locale);

  final Locale locale;

  static AppLocalizations of(BuildContext context) {
    return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
  }

  Map<String, String> _localizedValues = {};

  Future<void> load() async {
    String fileName = 'assets/locales/${locale.languageCode}.arb';
    if (locale.countryCode != null && locale.countryCode!.isNotEmpty) {
      fileName = 'assets/locales/${locale.languageCode}_${locale.countryCode}.arb';
    }

    String jsonString = await rootBundle.loadString(fileName);
    Map<String, dynamic> jsonMap = jsonDecode(jsonString);

    _localizedValues = jsonMap.mapKeys((key) => key as String).cast<String, String>();
  }

  String translate(String key) {
    return _localizedValues[key] ?? key;
  }
}

class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
  const AppLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) {
    return ['en', 'zh'].contains(locale.languageCode);
  }

  @override
  Future<AppLocalizations> load(Locale locale) async {
    AppLocalizations localizations = new AppLocalizations(locale);
    await localizations.load();
    return localizations;
  }

  @override
  bool shouldReload(AppLocalizationsDelegate oldDelegate) {
    return false;
  }
}

lib/main.dart

import 'package:flutter/material.dart';
import 'l10n/messages.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: [
        AppLocalizationsDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        Locale('en', ''),
        Locale('zh', ''),
      ],
      home: MyHomePage(),
    );
  }
}

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

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

  void changeLanguage(Locale locale) {
    setState(() {
      _locale = locale;
    });
  }

  @override
  Widget build(BuildContext context) {
    final appLocalizations = AppLocalizations.of(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(appLocalizations.translate('welcome_message')),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(appLocalizations.translate('welcome_message')),
            Text(appLocalizations.translate('goodbye_message')),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => changeLanguage(Locale('en')),
              child: Text('English'),
            ),
            ElevatedButton(
              onPressed: () => changeLanguage(Locale('zh')),
              child: Text('中文'),
            ),
          ],
        ),
      ),
    );
  }
}

4. 配置资源文件

确保在pubspec.yaml中配置资源文件路径:

flutter:
  assets:
    - assets/locales/

5. 运行应用程序

现在,当你运行应用程序时,你应该能够看到初始加载的英语文本。你可以通过点击按钮来切换到中文,并验证文本是否正确更新。

这个示例展示了如何使用flutter_localizationsintl包来实现Flutter应用程序的国际化。你可以根据需要扩展这个示例,以支持更多的语言和更复杂的本地化需求。

回到顶部