Flutter本地化管理插件json_localizations的使用

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

Flutter本地化管理插件json_localizations的使用

json_localizations 是一个用于 Flutter 的轻量级 JSON 本地化包。通过为每种语言添加一个 JSON 文件来表示键值对,可以实现应用的本地化。

安装

pubspec.yaml 文件中添加 json_localizationsflutter_localizations 作为依赖项。

dependencies:
  flutter_localizations:
    sdk: flutter
  json_localizations:

添加每种语言的 JSON 文件

pubspec.yaml 文件中描述每种语言的 JSON 文件路径。

flutter:
  assets:
    - assets/json_translations/

JSON 文件名必须与 supportedLocales 中的语言和国家代码完全匹配。例如,如果 Locale('en', 'US') 需要有一个对应的 assetPath/en-US.json 文件。

MaterialApp 中添加 JsonLocalizationsDelegate

MaterialApp 中添加 JsonLocalizationsDelegate 并设置支持的语言和地区代码。

MaterialApp(
  localizationsDelegates: [
    // 从 flutter_localization 导入的代理
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
    // 从 json_localizations 导入的代理
    JsonLocalizationsDelegate(path: 'assets/json_translations'),
  ],
  supportedLocales: [
    Locale('en'),
    Locale('nb'),
  ],
)

iOS 注意事项

在 iOS 上,需要在 ios/Runner/Info.plist 文件中添加支持的语言。

<key>CFBundleLocalizations</key>
<array>
    <string>en-GB</string>
    <string>en</string>
    <string>nb</string>
</array>

格式

示例 JSON 文件:

{
    "hello": "hello",
    "bye": "bye",
    "items": [ "one", "two", "three" ],
    "count": 1
}

提示: 可以存储任何类型的 JSON 数据,如字符串、字符串数组或数字。

API

获取当前语言的值:

JsonLocalizations.of(context)?.value('hello')

可以轻松地添加扩展方法到 String 类:

extension LocalizedString on String {
  String tr(BuildContext context) => JsonLocalizations.of(context)!.value(this);
}

这样就可以用以下方式调用:

'hello'.tr(context)

示例

查看完整的示例代码:

import 'package:flutter/material.dart';

import 'package:json_localizations/json_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        ...GlobalMaterialLocalizations.delegates,
        JsonLocalizationsDelegate(path: 'assets/json_translations'),
      ],
      supportedLocales: const [
        Locale('en'),
        Locale('nb'),
      ],
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(),
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('json_localizations'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Text(JsonLocalizations.of(context)?.value('hello')),
          const SizedBox(height: 12),
          Text(JsonLocalizations.of(context)?.value('bye')),
          const Divider(),
          ...JsonLocalizations.of(context)
              ?.value('items')
              .map((text) => Text(text))
              .toList(),
          const Divider(),
          Text(JsonLocalizations.of(context)!.value('count').toString()),
        ],
      ),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何在Flutter项目中使用json_localizations插件进行本地化管理的代码示例。json_localizations插件并不是Flutter官方推荐的插件,但你可以通过自定义方式实现类似的功能。通常,Flutter推荐使用flutter_localizations包以及arb文件来进行本地化。不过,为了符合你的要求,这里我们将展示一个使用JSON文件进行本地化的简单示例。

步骤 1: 添加依赖

首先,确保你的pubspec.yaml文件中没有特定于json_localizations的依赖,因为这不是一个官方的Flutter插件。但是,你可能需要添加一些基本的依赖,比如flutterintl(用于日期和数字格式化等)。

dependencies:
  flutter:
    sdk: flutter
  intl: ^0.17.0 # 或者最新版本

步骤 2: 创建JSON本地化文件

在你的项目根目录下创建一个assets文件夹,并在其中创建不同语言的JSON文件,例如en.jsonzh.json

assets/en.json

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

assets/zh.json

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

步骤 3: 加载和解析JSON文件

接下来,你需要编写一个类来加载和解析这些JSON文件。

lib/localization.dart

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

class Localization {
  static Localization _instance;
  Map<String, Map<String, String>> _localizedValues;

  Localization._();

  factory Localization() {
    if (_instance == null) {
      _instance = Localization._();
      _instance.load();
    }
    return _instance;
  }

  Future<void> load() async {
    String locale = Localizations.localeOf(null).languageCode;
    String jsonString = await rootBundle.loadString('assets/$locale.json');
    Map<String, dynamic> jsonMap = jsonDecode(jsonString);
    _localizedValues = {locale: Map.from(jsonMap)};
  }

  String translate(String key) {
    Locale locale = Localizations.localeOf(null);
    return _localizedValues[locale.languageCode]?[key] ?? key;
  }
}

步骤 4: 创建Delegate并注册Localizations

为了能够在整个应用中使用我们的本地化类,我们需要创建一个LocalizationsDelegate

lib/localization_delegate.dart

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

class LocalizationDelegate extends LocalizationsDelegate<Localization> {
  const LocalizationDelegate();

  @override
  bool isSupported(Locale locale) {
    // 这里你可以添加支持的语言列表
    return ['en', 'zh'].contains(locale.languageCode);
  }

  @override
  Future<Localization> load(Locale locale) async {
    Localization localization = Localization();
    await localization.load();
    return localization;
  }

  @override
  bool shouldReload(LocalizationDelegate oldDelegate) => false;
}

步骤 5: 在MaterialApp中使用Delegate

最后,在你的MaterialApp中使用这个delegate。

lib/main.dart

import 'package:flutter/material.dart';
import 'localization.dart';
import 'localization_delegate.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: [
        const LocalizationDelegate(),
        // 添加官方本地化的delegate
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        Locale('en', ''),
        Locale('zh', ''),
      ],
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final Localization localization = Localization();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(localization.translate('welcome_message')),
      ),
      body: Center(
        child: Text(
          localization.translate('goodbye_message'),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 切换语言示例(这里只是简单展示,实际应用中需要更复杂的逻辑)
          Locale newLocale = Localizations.localeOf(context).languageCode == 'en'
              ? Locale('zh')
              : Locale('en');
          Localizations.override(
            context,
            Locale(newLocale.languageCode),
            () {
              // 这里可能需要重新加载数据或刷新UI
              // 例如使用Provider、Bloc等状态管理库来通知UI更新
            },
          );
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

注意:上面的代码示例中,floatingActionButton的点击事件只是简单地切换了locale,并没有实际重新加载JSON文件。在实际应用中,你可能需要更复杂的状态管理来处理语言切换,并重新加载本地化数据。这通常可以通过使用Provider、Bloc或Riverpod等状态管理库来实现。

此外,Flutter官方推荐使用arb文件和flutter_localizations包来进行本地化,因为它们提供了更完整和灵活的解决方案。上述示例仅用于展示如何使用JSON文件进行本地化,并不建议用于生产环境。

回到顶部