flutter插件 - intl(国际化)

简介

官方文档

需要先配置flutter_localizations

使用intl_translation包的工具来提取代码中的字符串到一个arb文件

intl_translation开发环境才用到,配置到dev_dependencies下面

使用

  • 修改pubspec.yaml文件,添加依赖intl
# ... dev_dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter # ... intl: ^0.16.1 dev_dependencies: # ... intl_translation: 0.17.9 # ...
  • lib/i18n/目录下添加app_localizations.dart文件,用来实现LocalizationsDelegate
import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:xxxx/i18n/messages_all.dart'; class AppLocalizations { AppLocalizations(this.localeName); final String localeName; static Future<AppLocalizations> load(Locale locale) { final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString(); final String localeName = Intl.canonicalizedLocale(name); return initializeMessages(localeName).then((_) { return AppLocalizations(localeName); }); } static AppLocalizations of(BuildContext context) { return Localizations.of<AppLocalizations>(context, AppLocalizations); } String get verificationCodeLogin { return Intl.message( 'Verification Code Login', name: 'verificationCodeLogin', desc: 'Title for the Login page', locale: localeName ); } String get passwordLogin { return Intl.message( 'Password Login', name: 'passwordLogin', desc: 'Password Login', locale: localeName ); } String get login { return Intl.message( 'Login', name: 'login', desc: 'Login', locale: localeName, ); } String get forgotPasswordLink { return Intl.message( 'Forgot Password', name: 'forgotPasswordLink', desc: 'Forgot Password', locale: localeName ); } String get inputPasswordHint { return Intl.message( 'Please enter the password', name: 'inputPasswordHint', desc: 'Please enter the password', locale: localeName ); } String get inputUsernameHint { return Intl.message( 'Please input username', name: 'inputUsernameHint', desc: 'Please input username', locale: localeName ); } String get noAccountRegisterLink { return Intl.message( 'No account yet? Register now', name: 'noAccountRegisterLink', desc: 'No account yet? Register now', locale: localeName ); } String get register { return Intl.message( 'Register', name: 'register', desc: 'Register', locale: localeName ); } String get openYourAccount { return Intl.message( 'Open your account', // 开启你的账号 name: 'openYourAccount', desc: 'Open your account', locale: localeName ); } String get inputPhoneHint { return Intl.message( 'Please enter phone number', // 请输入手机号 name: 'inputPhoneHint', desc: 'Please enter phone number', locale: localeName ); } String get inputVerificationCodeHint { return Intl.message( 'Please enter verification code', // 请输入验证码 name: 'inputVerificationCodeHint', desc: 'Please enter verification code', locale: localeName ); } String get inputPhoneInvalid { return Intl.message( 'Please input valid mobile phone number', // 请输入有效的手机号 name: 'inputPhoneInvalid', desc: 'Please input valid mobile phone number', locale: localeName ); } String get verificationButton { return Intl.message( 'Not really sent, just log in!', // 并没有真正发送哦,直接登录吧! name: 'verificationButton', desc: 'Not really sent, just log in!', locale: localeName, ); } String get getVerificationCode { return Intl.message( 'Get verification code', // 获取验证码 name: 'getVerificationCode', desc: 'Get verification code', locale: localeName, ); } String get resetLoginPassword { return Intl.message( 'Reset Login Password', // 获取验证码 name: 'resetLoginPassword', desc: 'Reset login password', locale: localeName, ); } //Note: Unregistered mobile phone number, please String get registeredTips { return Intl.message( 'Unregistered mobile phone number, please ', name: 'registeredTips', desc: 'Registered Tips', locale: localeName ); } String get confirm { return Intl.message( 'Confirm', name: 'confirm', locale: localeName, ); } } class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> { const AppLocalizationsDelegate(); @override bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode); @override Future<AppLocalizations> load(Locale locale) => AppLocalizations.load(locale); @override bool shouldReload(LocalizationsDelegate<AppLocalizations> old) => false; }
  • 在项目根目录下创建asstes/i18n-arb/目录

  • 执行以下命令在asstes/i18n-arb/目录下生成intl_messags.arb

flutter packages pub run intl_translation:extract_to_arb --output-dir=assets/i18n-arb lib/i18n/app_localizations.dart
  • asstes/i18n-arb/目录下新建intl_en.arb。也可以直接将intl_messags.arb复制一份修改
{
  "verificationCodeLogin": "Verification Code Login",
  "passwordLogin": "Password Login",
  "login": "Login",
  "forgotPasswordLink": "Forgot Password",
  "inputPasswordHint": "Please enter the password",
  "inputUsernameHint": "Please input username",
  "noAccountRegisterLink": "No account yet? Register now",
  "register": "Register",
  "openYourAccount": "Open your account",
  "inputPhoneHint": "Please enter phone number",
  "inputVerificationCodeHint": "Please enter verification code",
  "inputPhoneInvalid": "Please input valid mobile phone number",
  "verificationButton": "Not really sent, just log in!",
  "getVerificationCode": "Get verification code",
  "confirm": "Confirm",
  "resetLoginPassword": "Reset Login Password",
  "registeredTips": "Unregistered mobile phone number, please "
}
  • asstes/i18n-arb/目录下新建intl_zh.arb
{
  "verificationCodeLogin": "验证码登录",
  "passwordLogin": "密码登录",
  "login": "登录",
  "forgotPasswordLink": "忘记密码",
  "inputPasswordHint": "请输入密码",
  "inputUsernameHint": "请输入账号",
  "noAccountRegisterLink": "还没账号?快去注册",
  "register": "注册",
  "openYourAccount": "开启你的账号",
  "inputPhoneHint": "请输入手机号",
  "inputVerificationCodeHint": "请输入验证码",
  "inputPhoneInvalid": "请输入有效的手机号",
  "verificationButton": "并没有真正发送哦,直接登录吧!",
  "getVerificationCode": "获取验证码",
  "confirm": "确认",
  "resetLoginPassword": "重置登录密码",
  "registeredTips": "提示:未注册账号的手机号,请先"
}
  • 执行以下命令,根据arb生成dart文件。执行完之后会在lib/i18n/目录下生成messages_messages.dartmessages_all.dartmessages_en.dartmessages_zh.dart文件
# 非 Windows 系统 flutter packages pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/i18n/app_localizations.dart assets/i18n-arb/intl_*.arb # Windows 系统:通配符*识别不了。需要转的都写出来,暂时没有找到其他好的办法 flutter packages pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/i18n/app_localizations.dart assets/i18n-arb/intl_messages.arb assets/i18n-arb/intl_en.arb assets/i18n-arb/intl_zh.arb
  • 修改lib/main.dart文件,将所有的部分连接起来
MaterialApp( // ... localizationsDelegates: [ AppLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate ], supportedLocales: <Locale>[ Locale('zh', 'CN'), Locale('en', 'US') ], }
  • 代码中使用
import 'package:xxxx/i18n/app_localizations.dart'; AppLocalizations.of(context).verificationCodeLogin

将Intl.message分离

  • lib/i18n/目录下新建localization_messages.dart文件
import 'package:intl/intl.dart'; class LocalizationMessagesMixin { String localeName; String get verificationCodeLogin { return Intl.message( 'Verification Code Login', name: 'verificationCodeLogin', desc: 'Title for the Login page', locale: localeName ); } String get passwordLogin { return Intl.message( 'Password Login', name: 'passwordLogin', desc: 'Password Login', locale: localeName ); } String get login { return Intl.message( 'Login', name: 'login', desc: 'Login', locale: localeName, ); } String get forgotPasswordLink { return Intl.message( 'Forgot Password', name: 'forgotPasswordLink', desc: 'Forgot Password', locale: localeName ); } String get inputPasswordHint { return Intl.message( 'Please enter the password', name: 'inputPasswordHint', desc: 'Please enter the password', locale: localeName ); } String get inputUsernameHint { return Intl.message( 'Please input username', name: 'inputUsernameHint', desc: 'Please input username', locale: localeName ); } String get noAccountRegisterLink { return Intl.message( 'No account yet? Register now', name: 'noAccountRegisterLink', desc: 'No account yet? Register now', locale: localeName ); } String get register { return Intl.message( 'Register', name: 'register', desc: 'Register', locale: localeName ); } String get openYourAccount { return Intl.message( 'Open your account', // 开启你的账号 name: 'openYourAccount', desc: 'Open your account', locale: localeName ); } String get inputPhoneHint { return Intl.message( 'Please enter phone number', // 请输入手机号 name: 'inputPhoneHint', desc: 'Please enter phone number', locale: localeName ); } String get inputVerificationCodeHint { return Intl.message( 'Please enter verification code', // 请输入验证码 name: 'inputVerificationCodeHint', desc: 'Please enter verification code', locale: localeName ); } String get inputPhoneInvalid { return Intl.message( 'Please input valid mobile phone number', // 请输入有效的手机号 name: 'inputPhoneInvalid', desc: 'Please input valid mobile phone number', locale: localeName ); } String get verificationButton { return Intl.message( 'Not really sent, just log in!', // 并没有真正发送哦,直接登录吧! name: 'verificationButton', desc: 'Not really sent, just log in!', locale: localeName, ); } String get getVerificationCode { return Intl.message( 'Get verification code', // 获取验证码 name: 'getVerificationCode', desc: 'Get verification code', locale: localeName, ); } String get resetLoginPassword { return Intl.message( 'Reset Login Password', // 获取验证码 name: 'resetLoginPassword', desc: 'Reset login password', locale: localeName, ); } //Note: Unregistered mobile phone number, please String get registeredTips { return Intl.message( 'Unregistered mobile phone number, please ', name: 'registeredTips', desc: 'Registered Tips', locale: localeName ); } String get confirm { return Intl.message( 'Confirm', name: 'confirm', locale: localeName, ); } }
  • 修改lib/i18n/app_localizations.dart文件
import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'localization_messages.dart'; import 'messages_all.dart'; class AppLocalizations with LocalizationMessagesMixin { AppLocalizations(this.localeName); final String localeName; static Future<AppLocalizations> load(Locale locale) { final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString(); final String localeName = Intl.canonicalizedLocale(name); return initializeMessages(localeName).then((_) { return AppLocalizations(localeName); }); } static AppLocalizations of(BuildContext context) { return Localizations.of<AppLocalizations>(context, AppLocalizations); } } class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> { const AppLocalizationsDelegate(); @override bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode); @override Future<AppLocalizations> load(Locale locale) => AppLocalizations.load(locale); @override bool shouldReload(LocalizationsDelegate<AppLocalizations> old) => false; }
  • 通过导出arb的命令修改
flutter packages pub run intl_translation:extract_to_arb --output-dir=assets/i18n-arb lib/i18n/localization_messages.dart
  • 通过arb生成dart文件的命令修改
# 非 Windows 系统 flutter packages pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/i18n/localization_messages.dart assets/i18n-arb/intl_*.arb # Windows 系统 flutter packages pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/i18n/localization_messages.dart assets/i18n-arb/intl_messages.arb assets/i18n-arb/intl_en.arb assets/i18n-arb/intl_zh.arb

命令脚本

  • Windows系统:根目录下新建intl.sh文件
flutter packages pub run intl_translation:extract_to_arb --output-dir=assets/i18n-arb lib/i18n/localization_messages.dart flutter packages pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/i18n/localization_messages.dart assets/i18n-arb/intl_*.arb
  • Windows系统:根目录下新建intl.cmd文件
flutter packages pub run intl_translation:extract_to_arb --output-dir=assets/i18n-arb lib/i18n/localization_messages.dart "&&" flutter packages pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/i18n/localization_messages.dart assets/i18n-arb/intl_messages.arb assets/i18n-arb/intl_en.arb assets/i18n-arb/intl_zh.arb

创作不易,若本文对你有帮助,欢迎打赏支持作者!

 分享给好友: