Flutter本地化映射插件localization_mapper_annotation的使用

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

Flutter本地化映射插件localization_mapper_annotation的使用

1. 整理后的内容中关于“Flutter本地化映射插件localization_mapper_annotation的使用”的完整示例demo

// 示例代码:app_localizations.dart
import 'package:flutter/material.dart';
import 'package:localization_mapper_annotation/localization_mapper_annotation.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Localization Mapper Example',
      locale: Locale('en', 'es'), // 设置默认语言为西班牙语
      localizationsDelegates: [
        DefaultLocalizationsDelegate(),
        AppLocalizationsDelegate(context),
      ],
      supportedLocales: [Locale('en', 'es')],
      builder: (context, widget) => Localizations.delegate,
    );
  }
}

class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
  final BuildContext context;

  AppLocalizationsDelegate(this.context);

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<AppLocalizations> getLocalizationsFuture(
      Locale locale, Locales locales, int version) async {
    return AppLocalizations.of(context);
  }
}
// 示例代码:generate_localization.sh
#!/bin/bash

# grant executable permissions (you should grant executable permissions at your will and not via scripts)
chmod +x ./replace_string.sh

# generate localization
(cd ../ &amp;&amp; flutter gen-l10n)

# mapper generator-config options:
# preferrably, you can choose what to generate as part of localization extension on build-context by parsing 
# required parameters in the `[@LocalizationMapperAnnotation](/user/LocalizationMapperAnnotation)` annotation
# 
# [@LocalizationMapperAnnotation](/user/LocalizationMapperAnnotation)(mapperExtension: MapperExtension(l10n: true, locale: true, l10nParser: true))

filePath="../lib/localization/gen-l10n/app_localizations.dart"
searchParameter="abstract class AppLocalizations {"
requiredImports=$(cat &lt;&lt; EOM
import 'package:localization_mapper_annotation/localization_mapper_annotation.dart';\n\
part 'app_localizations.g.dart';\n\n\
[@LocalizationMapperAnnotation](/user/LocalizationMapperAnnotation)()\n\
abstract class AppLocalizations {
EOM
)

# write imports and annotations to app_localization.dart file
echo "\nAdding required imports to generated app_localizations"
bash ./replace_string.sh "$filePath" "$searchParameter" "$requiredImports"

echo "\nGenerating app_localizations mapper files"
(cd ../ &amp;&amp; flutter pub run build_runner build --delete-conflicting-outputs)
EOM
)
// 示例代码:replace_string.sh
#!/bin/bash

# check if enough arguments were provided
if [ $# -lt 3 ]; then
    echo "Error: Not enough arguments provided."
    echo "Usage: $0 <input_file> <search_pattern> <replacement_string>"
    exit 1
fi

# assign input arguments to variables
input_file=$1
search_pattern=$2
replacement_string=$3

# check if the input file exists
if [ ! -f $input_file ]; then
    echo "Error: Input file does not exist."
    exit 1
fi

# backup the original file
cp $input_file "$input_file.bak"

# perform the search and replace and write the result to a new file
sed "s/$search_pattern/$replacement_string/i" $input_file &gt; "$input_file.tmp"

# check if the replacement was successful
if [ $? -ne 0 ]; then
    echo "Error: Replacement failed."
    exit 1
fi

# overwrite the original file with the new file
mv "$input_file.tmp" "$input_file"

echo "Replacement completed successfully."
// 示例代码:app_localizations.g.dart
// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'app_localizations.dart';

// **************************************************************************
// LocalizationMapperGenerator
// **************************************************************************

extension AppLocalizationsExtension on BuildContext {
  AppLocalizations get l10n =&gt; AppLocalizations.of(this)!;
  Locale get locale =&gt; Localizations.localeOf(this);
  String l10nParser(String translationKey, {List&lt;Object&gt;? arguments}) {
    const mapper = AppLocalizationsMapper();
    final object = mapper.toLocalizationMap(this)[translationKey];
    if (object is String) return object;
    assert(arguments != null, 'Arguments should not be null!');
    assert(arguments!.isNotEmpty, 'Arguments should not be empty!');
    return Function.apply(object, arguments);
  }
}

class AppLocalizationsMapper {
  const AppLocalizationsMapper();
  Map&lt;String, dynamic&gt; toLocalizationMap(BuildContext context) {
    return {
      'localeName': AppLocalizations.of(context)!.localeName,
      'application_name': AppLocalizations.of(context)!.application_name,
      'deposit_timeframe': AppLocalizations.of(context)!.deposit_timeframe,
      'balance_reverted': (currency) =&gt;
          AppLocalizations.of(context)!.balance_reverted(currency),
      'convert_before_withdraw': (convertFrom, convertTo) =&gt;
          AppLocalizations.of(context)!
              .convert_before_withdraw(convertFrom, convertTo),
      'convert_before_withdraw_again': (convertFrom, convertTo) =&gt;
          AppLocalizations.of(context)!
              .convert_before_withdraw_again(convertFrom, convertTo),
    };
  }
}
// 示例代码:app_localizations.dart
import 'package:flutter/material.dart';
import 'package:localization_mapper_annotation/localization_mapper_annotation.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Localization Mapper Example',
      locale: Locale('en', 'es'), // 设置默认语言为西班牙语
      localizationsDelegates: [
        DefaultLocalizationsDelegate(),
        AppLocalizationsDelegate(context),
      ],
      supportedLocales: [Locale('en', 'es')],
      builder: (context, widget) => Localizations.delegate,
    );
  }
}

class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
  final BuildContext context;

  AppLocalizationsDelegate(this.context);

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<AppLocalizations> getLocalizationsFuture(
      Locale locale, Locales locales, int version) async {
    return AppLocalizations.of(context);
  }
}

使用说明

  1. 安装依赖

    dependencies:
      flutter:
        sdk: flutter
    
      flutter_localizations:
        sdk: flutter
    
      localization_mapper_annotation: ^latest-version
    
    dev_dependencies:
      build_runner: ^2.3.3
    
      localization_mapper_generator: ^latest-version
    
  2. 定义shell脚本

    # replace_string.sh
    # 检查是否提供了足够的参数
    if [ $# -lt 3 ]; then
        echo "错误:提供的参数不足。"
        echo "用法:$0 <输入文件> <搜索模式> <替换字符串>"
        exit 1
    fi
    
    # 将输入参数分配给变量
    input_file=$1
    search_pattern=$2
    replacement_string=$3
    
    # 检查输入文件是否存在
    if [ ! -f $input_file ]; then
        echo "错误:输入文件不存在。"
        exit 1
    fi
    
    # 备份原始文件
    cp $input_file "$input_file.bak"
    
    # 执行搜索和替换,并将结果写入新文件
    sed "s/$search_pattern/$replacement_string/i" $input_file &gt; "$input_file.tmp"
    
    # 检查替换是否成功
    if [ $? -ne 0 ]; then
        echo "错误:替换失败。"
        exit 1
    fi
    
    # 用新文件覆盖原始文件
    mv "$input_file.tmp" "$input_file"
    
    echo "替换完成成功。"
    
  3. 生成本地化文件

    # generate_localization.sh
    # 授予replace_string.sh可执行权限(根据需要授予,而不是通过脚本来实现)
    chmod +x ./replace_string.sh
    
    # 生成本地化文件
    (cd ../ &amp;&amp; flutter gen-l10n)
    
    # mapper生成配置选项:
    # 最好选择在构建上下文中生成本地化扩展部分,通过解析
    # 在注解中的所需参数
    # [@LocalizationMapperAnnotation](/user/LocalizationMapperAnnotation)(mapperExtension: MapperExtension(l10n: true, locale: true, l10nParser: true))
    
    filePath="../lib/localization/gen-l10n/app_localizations.dart"
    searchParameter="abstract class AppLocalizations {"
    requiredImports=$(cat &lt;&lt; EOM
    import 'package:localization_mapper_annotation/localization_mapper_annotation.dart';\n\
    part 'app_localizations.g.dart';\n\n\
    [@LocalizationMapperAnnotation](/user/LocalizationMapperAnnotation)()\n\
    abstract class AppLocalizations {
    EOM
    )
    
    # 将导入和 注释写入生成的app_localizations文件
    echo "\n添加所需的导入到生成的app_localizations"
    bash ./replace_string.sh "$filePath" "$searchParameter" "$requiredImports"
    
    echo "\n生成app_localizations映射文件"
    (cd ../ &amp;&amp; flutter pub run build_runner build --delete-conflicting-outputs)
    

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

1 回复

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


当然,关于 localization_mapper_annotation 插件在 Flutter 本地化中的使用,下面是一个简单的代码示例,展示了如何使用该插件来简化和自动化本地化映射的过程。

首先,确保你已经在 pubspec.yaml 文件中添加了 localization_mapperlocalization_mapper_annotation 依赖:

dependencies:
  flutter:
    sdk: flutter
  localization_mapper: ^最新版本号
  localization_mapper_annotation: ^最新版本号

然后运行 flutter pub get 来获取这些依赖。

接下来,让我们一步一步地展示如何使用 localization_mapper_annotation 来定义和使用本地化字符串。

  1. 定义本地化字符串

创建一个 strings.dart 文件,使用 @Localizations()@JsonKey() 注解来定义本地化字符串。例如:

import 'package:flutter/material.dart';
import 'package:localization_mapper/localization_mapper.dart';
import 'package:localization_mapper_annotation/localization_mapper_annotation.dart';

part 'strings.g.dart';

@Localizations()
class Strings {
  Strings(this.locale);

  final Locale locale;

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

  @JsonKey(name: 'welcome_message')
  String get welcomeMessage => Intl.message('Welcome to our app!', name: 'welcome_message');

  @JsonKey(name: 'goodbye_message')
  String get goodbyeMessage => Intl.message('Goodbye!', name: 'goodbye_message');
}

注意这里使用了 part 'strings.g.dart';,这个部分将由生成器自动填充。

  1. 生成本地化映射文件

你需要使用 build_runner 来生成本地化映射文件。在你的项目根目录下运行以下命令:

flutter pub run build_runner build

这将生成 strings.g.dart 文件,其中包含从 JSON 文件映射到 Dart 类的代码。

  1. 创建 JSON 本地化文件

为每个语言创建一个 JSON 文件,例如 en.jsonzh.json

en.json:

{
  "welcome_message": "Welcome to our app!",
  "goodbye_message": "Goodbye!"
}

zh.json:

{
  "welcome_message": "欢迎来到我们的应用!",
  "goodbye_message": "再见!"
}
  1. 加载本地化资源

在你的 main.dart 文件中,设置 LocalizationsDelegateMaterialAppsupportedLocaleslocaleListResolutionCallback

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'strings.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: [
        Strings.delegate, // 添加 Strings delegate
        // 其他 delegates,例如 GlobalMaterialLocalizations.delegate 等
      ],
      supportedLocales: [
        Locale('en', ''),
        Locale('zh', ''),
      ],
      localeListResolutionCallback: (List<Locale> locales, Iterable<Locale> supportedLocales) {
        for (Locale locale in locales) {
          if (supportedLocales.contains(locale)) {
            return locale;
          }
        }
        return supportedLocales.first;
      },
      home: MyHomePage(),
    );
  }
}

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

在这个示例中,我们定义了一个 Strings 类来包含我们的本地化字符串,并使用 @JsonKey() 注解来映射 JSON 文件中的键。然后,我们生成了本地化映射文件,并在 MaterialApp 中设置了本地化委托和支持的语言环境。

这样,当你更改设备的语言设置时,应用将自动显示相应的本地化字符串。

回到顶部