Flutter国际化插件playx_localization的使用

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

Flutter国际化插件playx_localization的使用

简介

通过Playx Localization简化应用程序的本地化管理。该插件提供了简单实现和丰富的工具来轻松管理和更新应用程序的本地化。

特点

  • 易于管理区域设置:创建和管理应用程序区域设置,轻松切换。
  • 无上下文的本地化:不再需要BuildContext,使本地化更简单。
  • 支持Dart隔离:支持Dart隔离以进行后台本地化任务。
  • 多种文件格式:从JSON、CSV、YAML、XML等加载翻译。
  • 响应区域设置更改:自动响应并持久化应用内的区域设置更改。
  • 高级本地化:支持复数、性别、嵌套、RTL区域设置等。
  • 回退区域设置处理:定义回退区域设置键以实现无缝的本地化回退。

安装

将Playx Localization集成到你的Flutter项目中非常简单。请遵循以下步骤:

添加依赖

在你的pubspec.yaml文件的dependencies部分添加以下行:

dependencies:
  playx_localization: ^0.1.0
添加翻译文件

将你的本地化文件组织在assets/translations目录下。文件应遵循特定的命名约定:

assets
└── translations
    ├── {languageCode}.{ext}                  
    └── {languageCode}-{countryCode}.{ext}    

例如:

assets
└── translations
    ├── en.json  
    └── en-US.json   
声明本地化资源

pubspec.yaml文件中声明本地化目录:

flutter:  
  assets:  
    - assets/translations/
加载其他资源中的翻译

Playx Localization支持从各种来源加载翻译,如JSON、CSV、HTTP、XML、YAML文件等。更多信息可参见Easy Localization Loader

iOS注意事项

要在iOS设备上启用翻译,请将支持的语言添加到ios/Runner/Info.plist文件中,具体信息可参见这里

使用

使用Playx Localization在应用中涉及几个简单的步骤:

启动核心功能

使用你所需的区域设置配置初始化Playx核心包:

void main() async {    
  WidgetsFlutterBinding.ensureInitialized();
  
  // 定义支持的区域设置和其他配置
  const locales = [  
    XLocale(id: 'en', name: 'English', languageCode: 'en'),  
    XLocale(id: 'ar', name: 'العربية', languageCode: 'ar'),  
  ];  
  
  final config = PlayxLocaleConfig(  
    supportedLocales: locales,  
    startLocale: locales.first,  
    fallbackLocale: locales.first,  
    useFallbackTranslations: true,  
  );
  
  // 使用定义的配置启动Playx Localization
  await PlayxLocalization.boot(config: config);

  runApp(const MyApp());
}
使用PlayxLocalizationBuilder小部件

PlayxLocalizationBuilder小部件包裹你的MaterialAppCupertinoApp,以监听区域设置的变化:

class MyApp extends StatelessWidget {    
  const MyApp({Key? key});    
    
  @override    
  Widget build(BuildContext context) {  
    return PlayxLocalizationBuilder(builder: (context, locale) {  
      return MaterialApp(  
        supportedLocales: PlayxLocalization.supportedLocales,  
        localizationsDelegates: PlayxLocalization.localizationDelegates,  
        locale: locale.locale,  
        home: const MyHomePage(),  
      );  
    });  
  }    
}
PlayxLocaleConfig属性

使用PlayxLocaleConfig属性配置你的本地化偏好:

属性 必需 默认值 描述
supportedLocales 支持的区域设置列表
path ‘assets/translations’ 包含本地化文件的路径
assetLoader RootBundleAssetLoader() 本地化文件加载器,可以使用自定义加载器或默认加载器
fallbackLocale 当所需区域设置不可用时使用的回退区域设置
startLocale 应用程序启动时的初始区域设置。如果为null,则使用设备区域设置
saveLocale true 在设备存储中保存选择的区域设置
useFallbackTranslations true 如果找不到本地化键,则使用回退翻译
useOnlyLangCode false 仅使用语言代码读取本地化文件
更新应用程序区域设置

使用PlayxLocalization界面切换区域设置:

FloatingActionButton.extended(  
  onPressed: () {  
    PlayxLocalization.updateByIndex(  
      PlayxLocalization.isCurrentLocaleArabic() ? 0 : 1
    );  
  },  
  label: Text('change_language'.tr),  
  icon: const Icon(Icons.update),  
)
翻译

包使用Easy Localization来管理翻译和复数形式,如以下所示:

检索本地化文本:

Text('title').tr(context: context) // Text widget

print('title'.tr(context: context)); // String

var title = tr('title', context: context) // 静态函数

Text(context.tr('title')) // BuildContext扩展方法

tr函数传递上下文以确保当区域设置更改时,小部件正确重建。

参数

tr()函数传递参数以进行动态翻译:

名称 类型 描述
args <List<String>> 替换 {} 的本地化字符串列表
namedArgs <Map<String, String>> 替换名称键 {key_name} 的本地化字符串
gender <String> 根据性别字符串更改本地化字符串

示例:

{
   "msg": "{} are written in the {} language",
   "msg_named": "Playx localization is written in the {lang} language",
   "msg_mixed": "{} are written in the {lang} language",
   "gender": {  
      "male": "Hi man ;) {}",
      "female": "Hello girl :) {}",
      "other": "Hello {}"
   }
}

使用方式:

// args
Text('msg').tr(args: ['Playx localization', 'Dart']),

// namedArgs
Text('msg_named').tr(namedArgs: {'lang': 'Dart'}),

// args 和 namedArgs
Text('msg_mixed').tr(args: ['Playx localization'], namedArgs: {'lang': 'Dart'}),

// gender
Text('gender').tr(gender: _gender ? "female" : "male"),
复数

你可以使用复数形式进行翻译。

示例:

{
  "day": {
    "zero": "{} дней",
    "one": "{} день",
    "two": "{} дня",
    "few": "{} дня",
    "many": "{} дней",
    "other": "{} дней"
  },
  "money": {
    "zero": "You not have money",
    "one": "You have {} dollar",
    "many": "You have {} dollars",
    "other": "You have {} dollars"
  },
  "money_args": {
    "zero": "{} has no money",
    "one": "{} has {} dollar",
    "many": "{} has {} dollars",
    "other": "{} has {} dollars"
  },
  "money_named_args": {
    "zero": "{name} has no money",
    "one": "{name} has {money} dollar",
    "many": "{name} has {money} dollars",
    "other": "{name} has {money} dollars"
  }
}

使用方式:

// Text widget with format
Text('money').plural(1000000, format: NumberFormat.compact(locale: context.locale.toString())) // 输出: You have 1M dollars

// String
print('day'.plural(21)); // 输出: 21 день

// Static function
var money = plural('money', 10.23) // 输出: You have 10.23 dollars

// Text widget with plural BuildContext extension
Text(context.plural('money', 10.23))

// Static function with arguments
var money = plural('money_args', 10.23, args: ['John', '10.23'])  // 输出: John has 10.23 dollars

// Static function with named arguments
var money = plural('money_named_args', 10.23, namedArgs: {'name': 'Jane', 'money': '10.23'})  // 输出: Jane has 10.23 dollars
var money = plural('money_named_args', 10.23, namedArgs: {'name': 'Jane'}, name: 'money')  // 输出: Jane has 10.23 dollars
链接翻译

如果某个翻译键总是具有与另一个相同的实际文本,可以链接到它。要链接到另一个翻译键,只需在其内容前加上@:符号,后跟要链接到的完整键名,包括命名空间。

示例:

{
  "example": {
    "hello": "Hello",
    "world": "World!",
    "helloWorld": "@:example.hello @:example.world"
  }
}
print('example.helloWorld'.tr); // 输出: Hello World!

你还可以在链接的消息中进行嵌套的匿名和命名参数。

示例:

{
  "date": "{currentDate}.",
  "dateLogging": "INFO: the date today is @:date"
}
print(tr('dateLogging', namedArguments: {'currentDate': DateTime.now().toIso8601String()})); // 输出: INFO: the date today is 2020-11-27T16:40:42.657.
获取设备区域设置

获取设备区域设置:

print(PlayxLocalization.deviceLocale.toString()); // 输出: en_US
删除保存的区域设置

清除设备存储中的保存区域设置:

RaisedButton(
  onPressed: (){
    PlayxLocalization.deleteSaveLocale();
  },
  child: Text(LocaleKeys.reset_locale).tr(),
)
PlayxLocalization可用方法
方法 描述
currentIndex 获取当前XLocale索引。
currentXLocale 获取当前XLocale
currentLocale 获取当前区域设置。
deviceLocale 获取当前设备区域设置。
nextLocale 更新应用程序区域设置为下一个区域设置。
updateByIndex 通过索引更新应用程序区域设置。
updateById 通过XLocale ID更新应用程序区域设置。
updateTo 更新应用程序区域设置为特定的XLocale
updateToDeviceLocale 将应用程序区域设置更新为当前设备区域设置。
updateByLanguageCode 通过语言代码和国家代码(如果可用)更新应用程序区域设置。
supportedXLocales 获取在XLocaleConfig中配置的当前支持的XLocale
supportedLocales 获取当前支持的区域设置。
isCurrentLocaleArabic 检查当前区域设置是否为阿拉伯语。
isCurrentLocaleEnglish 检查当前区域设置是否为英语。
isCurrentLocaleRtl 检查当前区域设置是否为RTL。
currentLocaleToString 将当前[locale]转换为带有自定义[separator]表示语言的字符串。
deleteSavedLocale 从设备存储中删除保存的区域设置。
扩展与工具

该包还包括其他扩展和工具,可以帮助开发。

例如:

转换日期为格式化和本地化字符串
final dateText = DateTime.now().toFormattedDate(
    format: 'yyyy-MM-dd', 
    locale: PlayxLocalization.currentLocale.toStringWithSeparator()
);

print('Current date: $dateText');

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

1 回复

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


当然,以下是如何在Flutter项目中使用playx_localization插件进行国际化的代码示例。这个插件可以帮助你轻松地在Flutter应用中实现多语言支持。

1. 添加依赖

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

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

然后在你的项目根目录下运行flutter pub get来安装依赖。

2. 创建语言资源文件

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

assets/locales/en.json

{
  "greeting": "Hello",
  "farewell": "Goodbye"
}

assets/locales/zh.json

{
  "greeting": "你好",
  "farewell": "再见"
}

3. 配置pubspec.yaml

确保在pubspec.yaml中声明这些JSON文件为资源文件:

flutter:
  assets:
    - assets/locales/en.json
    - assets/locales/zh.json

4. 设置PlayxLocalization

在你的main.dart文件中,配置PlayxLocalization

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      // 使用PlayxLocalization
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        PlayxLocalization.delegate, // 添加这一行
      ],
      supportedLocales: PlayxLocalization.supportedLocales, // 添加这一行
      locale: PlayxLocalization.getLocale(), // 添加这一行
      home: MyHomePage(),
    );
  }
}

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

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

  @override
  Widget build(BuildContext context) {
    currentLocale = Localizations.localeOf(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Internationalization'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              PlayxLocalization.of(context)!.translate('greeting'),
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                PlayxLocalization.setLocale(Locale('en', 'US'));
              },
              child: Text('English'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                PlayxLocalization.setLocale(Locale('zh', 'CN'));
              },
              child: Text('中文'),
            ),
            SizedBox(height: 20),
            Text(
              PlayxLocalization.of(context)!.translate('farewell'),
              style: TextStyle(fontSize: 24),
            ),
          ],
        ),
      ),
    );
  }
}

5. 初始化语言数据

在你的项目入口文件(通常是main.dart)中初始化语言数据:

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

void initLocalizations(BuildContext context) async {
  // 加载语言资源
  Map<String, dynamic> enData = jsonDecode(await rootBundle.loadString('assets/locales/en.json'));
  Map<String, dynamic> zhData = jsonDecode(await rootBundle.loadString('assets/locales/zh.json'));

  // 设置语言数据
  PlayxLocalization.addData('en', enData);
  PlayxLocalization.addData('zh', zhData);

  // 设置默认语言
  PlayxLocalization.setLocale(Locale('en', 'US'));
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await initLocalizations(MaterialApp().buildContext!); // 注意:这里传入一个临时的context,实际项目中可能需要调整
  runApp(MyApp());
}

注意:上面的WidgetsFlutterBinding.ensureInitialized()MaterialApp().buildContext!在真实场景中可能并不适用,因为buildContextmain函数中是不可用的。一种常见的做法是使用runZonedGuarded或者将初始化逻辑放在MyAppbuild方法中,通过Localizations.localeOf(context)获取当前的Locale

这里为了简化示例,直接使用了MaterialApp().buildContext!,但在实际项目中需要适当调整。

这样,你就完成了Flutter项目中playx_localization插件的使用配置。现在,你可以通过点击按钮来切换应用的语言了。

回到顶部