flutter 国际化_从0开始设计Flutter独立APP | 第二篇: 完整的国际化语言支持
國際化語言的支持,是很多APP都有的一個強需求,APP無論大小,只要還不想放棄國外的客戶,一般就需要支持國際化。
官方支持
Flutter官方方案提供了國際化的基礎支持,如Flutter內置組件的國際化、語言代理、Widget使用語言包、語言設置回調等,并支持自定義第三方類來擴展,可以參考Flutter國際化文檔。
官方支持代碼示例:
class DemoLocalizations { DemoLocalizations(this.locale); final Locale locale; static DemoLocalizations of(BuildContext context) { return Localizations.of(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.yamlbutton: save: Save load: Loadusers: 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/cldr-spec/plural-rules。
使用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中設置和監聽本地語言包:
結尾
國際化支持,是一個移動端APP框架層的基礎能力,設計原則應該是使用無感知、靈活易擴展;但維護成本是難免有增加的,比如每次改文案要所有語言包同時更改。
講到這里,還并沒有完成基礎框架的搭建,后面我們會講解更多的Flutter架構設計內容,比如:通知、分享、UI設計等等。
持續分享閃點清單在Flutter上的開發經驗,閃點清單,一款懸浮清單軟件:
End
關注“閃點君”
隨時與我們交流
總結
以上是生活随笔為你收集整理的flutter 国际化_从0开始设计Flutter独立APP | 第二篇: 完整的国际化语言支持的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql慢查询开启语句分析_linux
- 下一篇: 往vxe-table添加渲染器怎么添_赚