从0开始设计Flutter独立APP | 第二篇: 完整的国际化语言支持
2020/6/28 14:26:24
本文主要是介绍从0开始设计Flutter独立APP | 第二篇: 完整的国际化语言支持,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
鉴于Flutter高性能渲染和跨平台的优势,闪点清单在移动端APP上,使用了完整的Flutter框架来开发。既然是完整APP,架构搭建完全不受历史Native APP的影响,没有历史包袱的沉淀,设计也能更灵活和健壮。
国际化语言的支持,是很多APP都有的一个强需求,APP无论大小,只要还不想放弃国外的客户,一般就需要支持国际化。
官方支持
Flutter官方方案提供了国际化的基础支持,如Flutter内置组件的国际化、语言代理、Widget使用语言包、语言设置回调等,并支持自定义第三方类来扩展,可以参考Flutter国际化文档。
官方支持代码示例:
class DemoLocalizations { DemoLocalizations(this.locale); final Locale locale; static DemoLocalizations of(BuildContext context) { return Localizations.of<DemoLocalizations>(context, DemoLocalizations); } static Map<String, Map<String, String>> _localizedValues = { 'en': { 'title': 'Hello World', }, 'es': { 'title': 'Hola Mundo', }, }; String get title { return _localizedValues[locale.languageCode]['title']; } }
官方方案的缺陷
官方的支持有几个缺陷:
- 依赖于BuildContext对象,在非Widget中调用时,需要层层传递BuildContext对象,或存储全局BuildContext对象。
- 在MaterialApp初始化前无法使用国际化(原因也是依赖于BuildContext对象)。
- 语言包定义推荐使用Map方式,无法利用静态语言的优势(语法提示、错误检查等);而为语言包每个属性自定义类和类字段,成本较高、使用和更新灵活性差。
i18n介绍
鉴于Flutter官方支持的缺陷,我们调研了很多第三方库,最终发现了i18n,并在此基础上、结合Flutter官方支持和自身封装,实现了更灵活易用的方案。
基础使用
i18n使用yaml格式来定义语言包,同时提供构建脚本一键生成Dart语言包Class。如下:
lib/messages.i18n.yaml button: save: Save load: Load users: welcome(String name): "Hello $name!" logout: Logout
该配置会生成几个Class:Messages、ButtonMessages、UserMessages,生成后的Dart文件使用方式如下:
Messages m = Messages(); debugPrint(m.users.logout); debugPrint(m.users.welcome('World'));
生成的Dart文件预览(开发时无需关心):
class Messages { const Messages(); ButtonMessages get button => ButtonExampleMessages(this); UsersMessages get users => UsersExampleMessages(this); } class ButtonMessages { final Messages _parent; const ButtonMessages(this._parent); String get save => "Save"; String get load => "Load"; } class UsersMessages { final Messages _parent; const UsersMessages(this._parent); String get logout => "Logout"; String welcome(String name) => "Hello $name!"; }
进阶功能
下面讲解一些进阶用法。
函数定义
i18n支持函数定义,并支持传参,如上述的welcome
函数:
debugPrint(m.users.welcome('World'));
参数定义基本没有限制,可以随意定义参数个数和类型。
内置函数
i18n支持了一些内置函数,用于做不同语言解析的体验优化,如:plural、cardinal、ordinal。具体规则和使用,可以参考这里:http://cldr.unicode.org/index...
使用Dart字符串模板
Dart字符串模板是非常强大的,而在i18n中,你可以使用字符串模板(这点非常赞),如:
count(int cnt): "You have created $cnt ${_plural(cnt, one:'invoice', many:'invoices')}."
前置编译
i18n依然依赖了Dart官方提供的builder_runner工具,来从yaml文件生成Dart文件,使用方式: flutter pub run build_runner build
。
语言包使用
前置编译后,每个语言包会生成N个Class(语言包的每一个分类或组合会生成一个Class文件),然后会生成一个根Class,我们可以直接使用根Class(当然也可以使用任何一个分类层级的Class)。
比如两个语言包文件: AppMessages.i18n.yaml
和AppMessages_en.i18n.yaml
(未加语言后缀的,会认为是默认语言包,因此AppMessages.i18n.yaml是默认语言包),会生成2个根Dart Class: class AppMessages
和class AppMessages_en extends AppMessages
。
AppMessages_en
自动继承自AppMessages
,因此我们可以直接使用AppMessages
类型来存储语言包,并在语言切换时重新为其实例化对应的子类:
AppMessages appMessages = new AppMessages(); resetLocalLang(String localeName) { switch (localeName) { case 'en': appMessages = AppMessages_en(); break; case 'zh': default: appMessages = AppMessages(); break; } }
然后你可以在任意地方使用语言包:
debugPrint('Load Button: ${appMessages.button.load}'); FlatButton( child: Text(appMessages.button.save), onPressed: () { /// 干点什么 }, )
Flutter集成
集成到Flutter,依然要依赖于官方的支持,在MaterialApp中设置和监听本地语言包:
@override Widget build(BuildContext context) { return MaterialApp( localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) { /// Local changed }, localizationsDelegates: [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, ], supportedLocales: ['zh', 'en'] .map((loc) => new Locale(loc)) .toList(growable: false), /// ... ); }
结尾
国际化支持,是一个移动端APP框架层的基础能力,设计原则应该是使用无感知、灵活易扩展;但维护成本是难免有增加的,比如每次改文案要所有语言包同时更改。
讲到这里,还并没有完成基础框架的搭建,后面我们会讲解更多的Flutter架构设计内容,比如:通知、分享、UI设计等等。
持续分享闪点清单在Flutter上的开发经验。闪点清单,一款悬浮清单软件:
这篇关于从0开始设计Flutter独立APP | 第二篇: 完整的国际化语言支持的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Vite多环境配置学习:新手入门教程
- 2024-11-23实现OSS直传,前端怎么实现?-icode9专业技术文章分享
- 2024-11-22在 HTML 中怎么实现当鼠标光标悬停在按钮上时显示提示文案?-icode9专业技术文章分享
- 2024-11-22html 自带属性有哪些?-icode9专业技术文章分享
- 2024-11-21Sass教程:新手入门及初级技巧
- 2024-11-21Sass学习:初学者必备的简单教程
- 2024-11-21Elmentplus入门:新手必看指南
- 2024-11-21Sass入门:初学者的简单教程
- 2024-11-21前端页面设计教程:新手入门指南
- 2024-11-21Elmentplus教程:初学者必备指南