Flutter国际化与JSON解析插件json_intl的使用

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

Flutter国际化与JSON解析插件json_intl的使用

Flutter应用程序在面向全球用户时,实现多语言支持(即国际化)是非常重要的。json_intl是一个基于Json文件的Flutter国际化库,它简化了Flutter应用中的多语言管理。本文将详细介绍如何使用json_intl进行Flutter应用的国际化,并提供一个完整的示例代码。

Getting Started

1. 添加依赖

首先,在项目的pubspec.yaml文件中添加json_intl依赖以及必要的本地化支持:

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

flutter:
  assets:
    - assets/intl/

确保替换latest_versionjson_intl的实际最新版本号。

2. 配置MaterialApp

接下来,在main.dart文件中配置MaterialApp以支持多语言:

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      onGenerateTitle: (BuildContext context) => JsonIntl.of(context).get(#app_name),
      home: const MyHomePage(),
      localizationsDelegates: const [
        JsonIntlDelegate(
          debug: false, // Set to true to display the translation keys
          availableLocales: ['fr', 'de'], // Not including the default language
        ),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('de'),
        Locale('en'),
        Locale('fr'),
      ],
    );
  }
}

这里我们指定了应用支持的语言列表,并且设置了JsonIntlDelegate来处理翻译逻辑。

3. iOS平台配置

对于iOS项目,还需要在ios/Runner/Info.plist中添加支持的语言:

<key>CFBundleLocalizations</key>
<array>
    <string>en</string>
    <string>fr</string>
</array>

这一步是为了让iOS系统知道你的应用支持哪些语言。

创建翻译文件

所有翻译文件都应该放在assets/intl/目录下:

  • strings.json:默认和回退文件。
  • strings-XX.json:每个语言对应一个文件,例如strings-fr.json代表法语。
  • strings-XX-AA.json:特定国家或地区的语言文件,如strings-en-uk.json

这些文件的内容是包含键值对的JSON对象,如下所示:

{
    "app_name": "Flutter Demo",
    "increment": "Increment",
    "title": "Flutter Demo Home Page"
}

使用翻译

通过JsonIntl.of(context).get()方法获取字符串资源,或者直接使用context.tr()扩展方法:

Text(JsonIntl.of(context).get(#app_name))
// 或者
Text(context.tr(#app_name))

对于复数形式,可以使用JsonIntl.of(context).count()方法:

JsonIntl.of(context).count(itemCount, #cart)

性别相关的翻译可以通过JsonIntl.of(context).gender()来处理:

JsonIntl.of(context).gender(JsonIntlGender.female, #child)

同时支持复数和性别的组合翻译:

JsonIntl.of(context).translate(#child, gender: JsonIntlGender.female, count: 3)

示例代码

下面是一个完整的示例代码,展示了如何结合以上知识点创建一个多语言支持的应用程序:

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      onGenerateTitle: (BuildContext context) => JsonIntl.of(context).get(#app_name),
      home: const MyHomePage(),
      localizationsDelegates: const [
        JsonIntlDelegate(
          debug: false, 
          availableLocales: ['fr', 'de'], 
        ),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('de'),
        Locale('en'),
        Locale('fr'),
      ],
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  MyHomePageState createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(JsonIntl.of(context).get(#title)),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(JsonIntl.of(context).count(
              _counter,
              #pushed,
              strict: false,
            )),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: context.tr(#increment),
        child: const Icon(Icons.add),
      ),
    );
  }
}

此代码段展示了如何在一个简单的计数器应用中实现多语言支持。希望这个例子能帮助你更好地理解json_intl的工作方式,并将其应用于自己的项目中。


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

1 回复

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


在Flutter项目中实现国际化(i18n)与JSON解析,结合json_intl插件可以大大简化这一过程。下面是一个详细的代码案例,展示如何使用json_intl插件来实现Flutter应用的国际化。

步骤一:添加依赖

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

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

步骤二:生成ARB文件

json_intl插件允许你从JSON文件生成ARB(Application Resource Bundle)文件,这是Flutter国际化支持的标准格式。

假设你有一个名为messages.json的文件,内容如下:

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

你可以使用json_intl命令行工具生成ARB文件。在命令行中运行以下命令:

flutter pub run json_intl:generate_from_json --input-file=assets/messages.json --output-dir=lib/l10n --locale=en,zh

这个命令会生成lib/l10n/messages_en.arblib/l10n/messages_zh.arb文件。

步骤三:设置国际化支持

lib目录下创建一个l10n文件夹,并添加生成的ARB文件。然后,你需要创建一个intl_messages.dart文件来加载这些ARB文件。

运行以下命令生成Dart本地化文件:

flutter pub run flutter_gen:generate

确保你的pubspec.yaml文件中包含对flutter_gen的依赖:

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_gen: ^x.y.z  # 请替换为最新版本号

步骤四:在Flutter应用中使用国际化

创建一个localization_service.dart文件来管理语言切换和本地化资源:

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:your_app/l10n/messages_all.dart'; // 自动生成的文件

class LocalizationService {
  static Future<Locale> load(Locale locale) async {
    final appLocalizationsDelegate = AppLocalizations.delegate;
    await appLocalizationsDelegate.load(locale);
    return locale;
  }

  static AppLocalizations of(BuildContext context) {
    return AppLocalizations.of(context)!;
  }
}

在你的MaterialApp中设置localizationsDelegatessupportedLocales

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:your_app/l10n/messages_all.dart'; // 自动生成的文件
import 'localization_service.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 StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    final localizations = LocalizationService.of(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(localizations.welcome!),
      ),
      body: Center(
        child: Text(localizations.goodbye!),
      ),
    );
  }
}

步骤五:语言切换

你可以通过以下方式实现语言切换功能:

class LanguageProvider with ChangeNotifier {
  Locale _locale;

  LanguageProvider() {
    _locale = Locale('en'); // 默认语言
  }

  Locale get locale => _locale;

  void changeLanguage(Locale newLocale) async {
    _locale = newLocale;
    await LocalizationService.load(_locale);
    notifyListeners();
  }
}

// 在你的应用中提供LanguageProvider
void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => LanguageProvider()),
      ],
      child: MyApp(),
    ),
  );
}

// 使用Consumer监听语言变化并重建UI
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final localizations = LocalizationService.of(context);
    final languageProvider = Provider.of<LanguageProvider>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text(localizations.welcome!),
        actions: [
          IconButton(
            icon: Icon(Icons.language),
            onPressed: () {
              showCupertinoModalPopup<void>(
                context: context,
                builder: (BuildContext context) {
                  return CupertinoActionSheet(
                    title: Text('Choose Language'),
                    actions: <Widget>[
                      CupertinoDialogAction(
                        isDefaultAction: true,
                        child: Text('English'),
                        onPressed: () {
                          Navigator.of(context).pop();
                          languageProvider.changeLanguage(Locale('en'));
                        },
                      ),
                      CupertinoDialogAction(
                        child: Text('中文'),
                        onPressed: () {
                          Navigator.of(context).pop();
                          languageProvider.changeLanguage(Locale('zh'));
                        },
                      ),
                    ],
                    cancelButton: CupertinoDialogAction(
                      child: Text('Cancel'),
                      isDefaultAction: true,
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                    ),
                  );
                },
              );
            },
          ),
        ],
      ),
      body: Center(
        child: Text(localizations.goodbye!),
      ),
    );
  }
}

通过上述步骤,你就可以在Flutter应用中实现国际化,并利用json_intl插件从JSON文件生成ARB文件,进而实现多语言支持。

回到顶部