藉助App Store與Google Play,全世界任何一個國家的使用者均可以使用咱們開發的應用,不過因爲應用的使用者來自不一樣國家,因此在應用正式上架以前須要讓應用可以支持多種語言,即應用的國際化。
在Flutter開發中,應用的國際化主要涉及語言和地區差別性配置兩個方面,它們是應用程序的組成部分之一。關於語言的國際化比較好理解,而地區差別性配置指的是根據國家風俗的不一樣進行的差別性配置。按照Flutter官方的適配方案,要在Flutter應用中實現語言的國際化,須要通過如下幾步。app
能夠發現,若是直接按照官方提供的國際化方案來進行應用適配,不只工做量大並且極易出錯。爲了達到快速適配,減小代碼編寫形成的錯誤,可使用Android Studio提供的Flutter i18n國際化插件。若是尚未安裝Flutter i18n插件,能夠打開Android Studio,而後依次選擇【Preference】→【Plugins】→【Marketplace】搜索Flutter i18n插件進行安裝,以下圖所示。
less
安裝完成以後,重啓Android Studio就可使用它進行Flutter的國際化適配了。須要說明的是,因爲最新版的Android Studio已經不支持使用應用市場的方式來安裝Flutter i18n插件,因此須要先從Jetbrains官網下載後再從本地進行安裝,以下圖所示。ide
因爲Flutter i18n插件須要依賴flutter_localizations插件包,因此執行國際化適配以前,還須要在pubspec.yaml文件中添加flutter_localizations依賴,以下所示。ui
dependencies: flutter_localizations: sdk: flutter
在命令行中使用flutter packages get命令拉取依賴。而後,在項目的根目錄下會自動生成一個res文件夾,該文件夾默認會包含一個strings_en.arb文件,arb文件的格式以下。spa
{ "app_name": "Flutter App internationalization", "main_title": "Flutter i18n", "main_content" : "You have click the button many times" }
arb文件是JSON格式的配置文件,能夠用來存放文案標識符和文案翻譯的鍵值對。事實上,這種將字符串文本分離成單獨文件的作法,能夠方便開發人員和翻譯人員分工協做,從而提升適配效率。
默認狀況下,系統只會生成英文資源配置strings_en.arb文件,若是要支持中文,則須要使用手動的方式在values目錄下增長一個strings_zh.arb文件。在res/values文件夾上右鍵,而後依次選擇【New】→【Arb File】→【Choose language】建立一個名爲strings_zh.arb的arb文件,並添加以下內容。插件
{ "app_name": "Flutter應用國際化", "main_title": "Flutter國際化", "main_content" : "點擊按鈕次數: $count" }
實際使用時,只須要修改res/values目錄下的arb文件內容,i18n插件就會自動生成對應的Dart轉換代碼,以下圖所示。
須要說明的是,因爲i18n.dart文件的代碼是由插件自動生成的,因此不要手動修改裏面的內容。接下來,還須要在應用程序的入口,即MaterialApp中設置國際化所需的兩個重要參數localizationsDelegates與supportedLocales,以下所示。命令行
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( localizationsDelegates: const [ S.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate ], supportedLocales: S.delegate.supportedLocales, home: MyHomePage(title: '本地化'), ); } }
其中,localizationsDelegates表示應用程序的翻譯回調,supportedLocales表示應用所支持的語言地區屬性,而S.delegate則是Flutter i18n插件自動生成的類,包含Flutter所支持的語言地區屬性以及對應的文案翻譯映射。在上面的代碼中,除了加入S.delegate外,還加入了GlobalMaterialLocalizations.delegate和GlobalWidgetsLocalizations.delegate這兩個回調。翻譯
前者爲Material組件庫提供的本地化的字符串和其餘值,它可使組件支持多語言,然後者則是用於定義組件默認的文本方向,從左到右或從右到左。之因此要加入這兩個回調,是由於Flutter提供的組件自己已經支持了國際化,因此不必再適配一遍。而參數supportedLocales則用於表示應用所支持的語言地區,它的格式以下。3d
const Locale('zh', 'CN') //中文簡體
其中,Locale類是用來標識用戶語言環境的,它由語言和國家兩個屬性構成。在上面的代碼中,咱們將它設置成S.delegate.supportedLocales,即當前設備的語言。完成上述應用程序的國際化配置操做後,接下來就能夠在程序中經過S.of(context)方式獲取arb文件中的內容了。下面是使用S.of(context)方式獲取arb文件中標題名字的例子,以下所示。代理
S.of(context).main_title //獲取標題
須要說明的是,使用上面的方式獲取翻譯文案的內容須要在能獲取到上下文的前提下才能生效,也就是說只能對MaterialApp的子組件纔會生效。所以,若是要對應用的標題進行國際化配置,直接使用上面的方式是不行的,不過可使用MaterialApp提供的onGenerateTitle回調方法來進行處理,以下所示。
onGenerateTitle: (context) { return S.of(context).app_name; },
對於應用界面文案的國際化則要相對簡單許多,直接使用S.of(context)方式拿到arb文件中翻譯文案,而後設置到界面便可。下面是對Flutter官方工程的國際化處理,代碼以下。
Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(S.of(context).main_title), centerTitle: true, ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text(S.of(context).main_content), Text('$_counter', style: Theme.of(context).textTheme.display1), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ); }
接下來,切換系統中的英文和中文,而後運行上面的代碼,能夠看到,應用的內容會隨着系統的語言進行切換,效果下圖所示。
不過,因爲iOS應用程序有一套自建的語言環境管理機制,因此使用上面的方式適配國際化對於iOS應用程序是無效的。爲了讓iOS應用程序也能支持國際化,還須要在原生iOS工程中進行額外的配置。
使用Xcode打開Flutter項目的iOS原生工程,切換到工程面板,而後在Localization選項配置中添加中文支持,以下圖所示。
完成上述iOS原生工程配置後,再次回到Flutter工程,選擇iOS模擬器運行程序,就能夠看到能夠正常的支持國際化了,以下圖所示。
能夠發行,國際化的核心就是語言差別配置抽取。與Flutter的國際化處理方式不一樣,原生Android和iOS應用適配國際化只須要按照要求將國際化資源放到對應的文件夾目錄,而後應用層代碼訪問國際化資源時就會自動根據語言地區進行適配。