Flutter资源管理(国际化)

Flutter资源管理

在pubspec.yaml中指定资源所在目录:

  assets:
    - images/
    - images/mic_status/

Asset 变体(variant)
在选择匹配当前设备分辨率的图片时,Flutter会使用到asset变体

/graphics/background.png
…/graphics/dark/background.png
…/my_icon.png
…/2.0x/my_icon.png
…/3.0x/my_icon.png
// 只需包含:
flutter:
  assets:
    - graphics/background.png
    - my_icon.png

加载assets
1 加载文本assets

// 建议使用 DefaultAssetBundle 来获取当前BuildContext的AssetBundle。 这种方法不是使用应用程序构建的默认asset bundle,而是使父级widget在运行时动态替换的不同的AssetBundle,这对于本地化或测试场景很有用
DefaultAssetBundle.of()

// 每个Flutter应用程序都有一个rootBundle对象, 通过它可以轻松访问主资源包,直接使用package:flutter/services.dart中全局静态的rootBundle对象来加载asset即可
rootBundle.loadString('assets/config.json');

2 加载图片

AssetImage('graphics/background.png'),
AssetImage('icons/heart.png', package: 'my_icons')

Flutter国际化

.arb( Application Resource Bundle) 基于json格式的资源文件,每个.arb文件都包含一个JSON表,该表从资源ID映射到本地化值,文件名包含已为其转换值的语言环境

在这里插入图片描述


使用

1 在pubspec.yaml中添加flutter_localizations依赖并执行flutter packages get

dependencies:
  flutter:
    sdk: flutter
  # international
  flutter_localizations:
    sdk: flutter

2 通过插件Flutter Intl
纯手动方式参考下方的补充标签
主要是将intl_xx.arb文件自动生成对应语言的message_xx.dart文件

(如要适用于ios和远端构建 ,则前面的步骤手动添加,然后执行一下intl_util.generate的命令,如android在gradle中执行,远端CI使用sh脚本直接执行)

2.1 初始化项目 Tools -> Flutter Intl -> Initialize for the Project
其实就是在pubspec.yaml下增加了

 flutter_intl:
  enabled: true
  
  // 可以自定义一些内容
  class_name: S  (自定义语言库Delegate的默认类名)  # Optional. Sets the name for the generated localization class. Default: S
  main_locale: en  (会根据这个对应的arb文件的字符串定义来生成相应的代码,即使别的arb文件没相关的字符串定义) # Optional. Sets the main locale used for generating localization files. Provided value should consist of language code and optional script and country codes separated with underscore (e.g. 'en', 'en_GB', 'zh_Hans', 'zh_Hans_CN'). Default: en
  arb_dir: lib/l10n # Optional. Sets the directory of your ARB resource files. Provided value should be a valid path on your system. arb文件存放的路径
  localizely: (Localizely platform可以帮你翻译你的主语言为其他语言)   # Optional settings if you use Localizely platform. Read more: https://localizely.com/flutter-localization-workflow 
    project_id: # Get it from the https://app.localizely.com/projects page.
    branch: # Get it from the “Branches” page on the Localizely platform, in case branching is enabled and you want to use a non-main branch.
    upload_overwrite: # Set to true if you want to overwrite translations with upload. Default: false
    upload_as_reviewed: # Set to true if you want to mark uploaded translations as reviewed. Default: false
    download_empty_as: # Set to empty|main|skip, to configure how empty translations should be exported from the Localizely platform. Default: empty
    ota_enabled: # Set to true if you want to use Localizely Over-the-air functionality. Default: false

并且在lib目录下生成了generated目录(存放如messages_all.dart、message_en.dart)和l10n目录(存放arb文件)

2.2 添加国家/地区语言 Tools -> Flutter Intl ->add locale
其实会在generated目录生成message_xx.dartI10n目录生成intl_xx.arb
手动方式则自己在I10n目录创建intl_xx.arb

2.3 在arb文件中添加你要的字符串,ide中ctrl+s保存一下,即会自动执行intl_util.generate的命令,命令会将字符串的key添加到l10n.dart文件中,将相应的字符串内容添加到message_xx.dart文件中
手动方式则执行intl_util.generate的命令:

在pubspec.yaml所在的目录执行
flutter --no-color pub global run intl_utils:generate

参考:https://pub.dev/packages/intl_utils

3 初始化

import 'package:flutter_localizations/flutter_localizations.dart';

 Widget build(BuildContext context) {
    return MaterialApp(
	  // 1 添加语言库delegates
      localizationsDelegates: [
        // 插件自动生成
        S.delegate,
	    GlobalMaterialLocalizations.delegate,
	    GlobalCupertinoLocalizations.delegate,
	    GlobalWidgetsLocalizations.delegate
      ],
      // 2 插件自动生成
	  supportedLocales: S.delegate.supportedLocales,

要设置支持同一个国家不同地区特色的语言:

默认仅提供美国英语本地化,要自己设置需要的国家、地区的语言
      supportedLocales: [
		const Locale('en', 'US'),
		const Locale('zh', 'CN'),
		// Full Chinese support for CN, TW, and HK
		const Locale.fromSubtags(languageCode: 'zh'), // generic Chinese 'zh'
		const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'), // generic simplified Chinese 'zh_Hans'
		const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'), // generic traditional Chinese 'zh_Hant'
		const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'), // 'zh_Hans_CN'
		const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'), // 'zh_Hant_TW'
		const Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'HK'), // 'zh_Hant_HK'
		],

4 资源使用

MaterialLocalizations.of(context).xxLable

补充:手动方式
2 添加自定义的语言库类,并绑定自定义的localizationsDelegate中

(1) 通过map的方式
创建一个语言库类,类中一个Map<String, Map<String, String>>,key为语言,第二个Map的key为字符串的id标识,value为具体字符串
并绑定自定义的localizationsDelegate中

class SimpleLocalizationsDelegate
    extends LocalizationsDelegate<SimpleLocalizations> {
  const SimpleLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode);

  @override
  Future<SimpleLocalizations> load(Locale locale) {
    return SynchronousFuture<SimpleLocalizations>(SimpleLocalizations(locale));
  }

  @override
  bool shouldReload(SimpleLocalizationsDelegate old) => false;
}

(2) 通过dart的intl
添加依赖:

dependencies:
  intl: ^0.15.7

dev_dependencies:
  intl_translation: ^0.17.3

创建一个语言库类,类中

class IntlLocalizations {
  static IntlLocalizations of(BuildContext context) {
    return Localizations.of<IntlLocalizations>(context, IntlLocalizations);
  }

  String get appName {
    return Intl.message('App Name');
  }

  String get helloWorld {
    return Intl.message('Hello world');
  }
}

执行flutter pub pub run intl_translation:extract_to_arb --output-dir=你想要的输出目录。这一操作将会在指定目录里生成一个名为 intl_messages.arb 的文件

然后可以复制多份,如intl_zh.arb等不同国家、地区语言的字符串资源文件

执行flutter pub pub run intl_translation:generate_from_arb --output-dir=输出目录 --no-use-deferred-loading IntlLocalizations所在文件 所有arb文件。这样会生成几个 messages_ 开头的 dart 文件

其中名为 messages_all.dart 的文件里,在 IntlLocalizations 中添加如下的方法:

static Future<IntlLocalizations> load(Locale locale) {
  final name =
    locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
  final localeName = Intl.canonicalizedLocale(name);
  return initializeMessages(localeName).then((_) {
    Intl.defaultLocale = localeName;
    return IntlLocalizations();
  });
}

再绑定自定义的localizationsDelegate中:

 @override
  Future<IntlLocalizations> load(Locale locale) {
    return IntlLocalizations.load(locale);
  }

参考:https://segmentfault.com/a/1190000022579469

问题1 无法找到intl
解决:

flutter pub global activate 'packageName'
flutter pub global activate 'intl_utils'

当你想从命令行运行某个 Package 中的可执行对象时你需要先激活它

问题2 找不到l10.dart文件
gradle的这个任务要执行

exec {
        println("###################execIntlTask########################")
        commandLine "flutter", "--no-color", "pub", 'global', 'run', 'intl_utils:generate'
        workingDir "../../flutter_module"
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值