【发布时间】:2021-04-21 01:16:12
【问题描述】:
根据Flutter docs,我们可以通过2种方法添加本地化消息:
方法一
-
将以下内容添加到
pubspec.yaml文件中。dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter intl: ^0.17.0 flutter: generate: true -
创建一个
<project-root>/l10n.yaml文件,其中包含:arb-dir: lib/l10n template-arb-file: app_en.arb output-localization-file: demo_localizations.dart -
在
<project-root/l10n.yaml>中,为您的翻译文件创建app_locale.arb。例如:app_en.arb
{ "@@locale": "en", "helloWorld": "Hello World!" }app_es.arb
{ "@@locale": "es", "helloWorld": "Hola Mundo!" } -
demo_localizations.dart将被生成并可以像这样导入到main.dart:import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/demo_localizations.dart'; class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( localizationsDelegates: DemoLocalizations.localizationsDelegates, supportedLocales: DemoLocalizations.supportedLocales, title: 'My app', home: ... , ); } }
方法二:为应用的本地化资源定义一个类
-
将以下内容添加到
pubspec.yaml文件中。dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter intl: ^0.17.0 intl_translation: flutter: generate: true -
创建一个使用
initializeMessages()和Intl.message()的DemoLocalizations类。class DemoLocalizations { DemoLocalizations(this.localeName); static Future<DemoLocalizations> load(Locale locale) { final String name = locale.countryCode == null || locale.countryCode!.isEmpty ? locale.languageCode : locale.toString(); final String localeName = Intl.canonicalizedLocale(name); return initializeMessages(localeName).then((_) { return DemoLocalizations(localeName); }); } static DemoLocalizations of(BuildContext context) { return Localizations.of<DemoLocalizations>(context, DemoLocalizations)!; } final String localeName; String get title { return Intl.message( 'Hello World', name: 'title', desc: 'Title for the Demo application', locale: localeName, ); } } -
创建一个
DemoLocalizationsDelegate类。class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> { const DemoLocalizationsDelegate(); @override bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode); @override Future<DemoLocalizations> load(Locale locale) => DemoLocalizations.load(locale); @override bool shouldReload(DemoLocalizationsDelegate old) => false; } -
运行
flutter pub run intl_translation:extract_to_arb --output-dir=lib/l10n lib/demo_localizations.dart生成
intl_messages.arb文件。将intl_en.arb和intl_es.arb添加为您的翻译文件。 -
以应用的根目录为当前目录,运行
flutter pub run intl_translation:generate_from_arb --output-dir=lib/l10n --no-use-deferred-loading lib/demo_localizations.dart lib/l10n/intl_*.arb为每个
intl_<locale>.arb文件和intl_messages_all.dart生成intl_messages_<locale>.dart,这会导入所有消息文件。 -
将所需的类导入
main.dart。import 'package:flutter/material.dart'; import 'demo_localizations.dart'; import 'package:intl/intl.dart'; import 'l10n/messages_all.dart'; class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( localizationsDelegates: DemoLocalizations.localizationsDelegates, supportedLocales: DemoLocalizations.supportedLocales, title: 'My app', home: ... , ); } }
这两种方法有什么不同吗?我能知道为什么我们使用方法 2,因为涉及的步骤更多吗?
【问题讨论】:
-
查看此博客roszkowski.dev/2021/i18n-in-flutter。现在更容易了,因为包处理所有创建/构建/设置文件
-
@Reign 这是否意味着方法 2 在引入方法 1 之前只是一种较旧的方法?
-
最简单的解决方案是使用get包
-
@Ranjit 我想使用本机解决方案,而不是依赖另一个包。另外,我询问的是决定背后的基本原理,而不是如何 使应用程序国际化。你没有回答我的问题。
标签: flutter dart localization internationalization