W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
如果我們的應(yīng)用要支持多種語(yǔ)言,那么我們需要“國(guó)際化”它。這意味著我們?cè)陂_(kāi)發(fā)時(shí)需要為應(yīng)用程序支持的每種語(yǔ)言環(huán)境設(shè)置“本地化”的一些值,如文本和布局。Flutter SDK 已經(jīng)提供了一些組件和類來(lái)幫助我們實(shí)現(xiàn)國(guó)際化,下面我們來(lái)介紹一下 Flutter 中實(shí)現(xiàn)國(guó)際化的步驟。
接下來(lái)我們以MaterialApp
類為入口的應(yīng)用來(lái)說(shuō)明如何支持國(guó)際化。
大多數(shù)應(yīng)用程序都是通過(guò)
MaterialApp
為入口,但根據(jù)低級(jí)別的WidgetsApp
類為入口編寫(xiě)的應(yīng)用程序也可以使用相同的類和邏輯進(jìn)行國(guó)際化。MaterialApp
實(shí)際上也是WidgetsApp
的一個(gè)包裝。
注意,”本地化的值和資源“是指我們針對(duì)不同語(yǔ)言準(zhǔn)備的不同資源,這些資源一般是指文案(字符串),當(dāng)然也會(huì)有一些其他的資源會(huì)根據(jù)不同語(yǔ)言地區(qū)而不同,比如我們需要顯示一個(gè)APP上架地的國(guó)旗圖片,那么不同 Locale 區(qū)域我們就需要提供不同的的國(guó)旗圖片。
默認(rèn)情況下,F(xiàn)lutter SDK 中的組件僅提供美國(guó)英語(yǔ)本地化資源(主要是文本)。要添加對(duì)其他語(yǔ)言的支持,應(yīng)用程序須添加一個(gè)名為“flutter_localizations”的包依賴,然后還需要在MaterialApp
中進(jìn)行一些配置。 要使用flutter_localizations
包,首先需要添加依賴到pubspec.yaml
文件中:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
接下來(lái),下載flutter_localizations
庫(kù),然后指定MaterialApp
的localizationsDelegates
和supportedLocales
:
import 'package:flutter_localizations/flutter_localizations.dart';
new MaterialApp(
localizationsDelegates: [
// 本地化的代理類
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // 美國(guó)英語(yǔ)
const Locale('zh', 'CN'), // 中文簡(jiǎn)體
//其它Locales
],
// ...
)
與
MaterialApp
類為入口的應(yīng)用不同, 對(duì)基于WidgetsApp
類為入口的應(yīng)用程序進(jìn)行國(guó)際化時(shí),不需要GlobalMaterialLocalizations.delegate
。
localizationsDelegates
列表中的元素是生成本地化值集合的工廠。GlobalMaterialLocalizations.delegate
為 Material 組件庫(kù)提供的本地化的字符串和其他值,它可以使 Material 組件支持多語(yǔ)言。 GlobalWidgetsLocalizations.delegate
定義組件默認(rèn)的文本方向,從左到右或從右到左,這是因?yàn)橛行┱Z(yǔ)言的閱讀習(xí)慣并不是從左到右,比如如阿拉伯語(yǔ)就是從右向左的。
supportedLocales
也接收一個(gè) Locale 數(shù)組,表示我們的應(yīng)用支持的語(yǔ)言列表,在本例中我們的應(yīng)用只支持美國(guó)英語(yǔ)和中文簡(jiǎn)體兩種語(yǔ)言。
Locale
(opens new window)類是用來(lái)標(biāo)識(shí)用戶的語(yǔ)言環(huán)境的,它包括語(yǔ)言和國(guó)家兩個(gè)標(biāo)志如:
const Locale('zh', 'CN') // 中文簡(jiǎn)體
我們始終可以通過(guò)以下方式來(lái)獲取應(yīng)用的當(dāng)前區(qū)域 Locale:
Locale myLocale = Localizations.localeOf(context);
Localizations
(opens new window)組件一般位于 widget 樹(shù)中其它業(yè)務(wù)組件的頂部,它的作用是定義區(qū)域 Locale 以及設(shè)置子樹(shù)依賴的本地化資源。 如果系統(tǒng)的語(yǔ)言環(huán)境發(fā)生變化,WidgetsApp (opens new window)將創(chuàng)建一個(gè)新的 Localizations 組件并重建它,這樣子樹(shù)中通過(guò)Localizations.localeOf(context)
獲取的 Locale 就會(huì)更新。
當(dāng)我們更改系統(tǒng)語(yǔ)言設(shè)置時(shí),APP 中的 Localizations 組件會(huì)重新構(gòu)建,Localizations.localeOf(context)
獲取的 Locale 就會(huì)更新,最終界面會(huì)重新 build 達(dá)到切換語(yǔ)言的效果。但是這個(gè)過(guò)程是隱式完成的,我們并沒(méi)有主動(dòng)去監(jiān)聽(tīng)系統(tǒng)語(yǔ)言切換,但是有時(shí)我們需要在系統(tǒng)語(yǔ)言發(fā)生改變時(shí)做一些事,比如系統(tǒng)語(yǔ)言切換為一種我們 APP 不支持的語(yǔ)言時(shí),我們需要設(shè)置一個(gè)默認(rèn)的語(yǔ)言,這時(shí)我們就需要監(jiān)聽(tīng) locale 改變事件。
我們可以通過(guò)localeResolutionCallback
或localeListResolutionCallback
回調(diào)來(lái)監(jiān)聽(tīng) locale 改變的事件,我們先看看localeResolutionCallback
的回調(diào)函數(shù)簽名:
Locale Function(Locale locale, Iterable<Locale> supportedLocales)
locale
的值為當(dāng)前的當(dāng)前的系統(tǒng)語(yǔ)言設(shè)置,當(dāng)應(yīng)用啟動(dòng)時(shí)或用戶動(dòng)態(tài)改變系統(tǒng)語(yǔ)言設(shè)置時(shí)此 locale 即為系統(tǒng)的當(dāng)前 locale。當(dāng)開(kāi)發(fā)者手動(dòng)指定 APP 的 locale 時(shí),那么此 locale 參數(shù)代表開(kāi)發(fā)者指定的 locale,此時(shí)將忽略系統(tǒng) locale 如: MaterialApp(
...
locale: const Locale('en', 'US'), //手動(dòng)指定locale
...
)
上面的例子中手動(dòng)指定了應(yīng)用 locale 為美國(guó)英語(yǔ),指定后即使設(shè)備當(dāng)前語(yǔ)言是中文簡(jiǎn)體,應(yīng)用中的 locale 也依然是美國(guó)英語(yǔ)。如果locale
為null
,則表示 Flutter 未能獲取到設(shè)備的 Locale 信息,所以我們?cè)谑褂?code>locale之前一定要先判空。
supportedLocales
為當(dāng)前應(yīng)用支持的 locale 列表,是開(kāi)發(fā)者在 MaterialApp 中通過(guò)supportedLocales
屬性注冊(cè)的。Locale
,此Locale
為 Flutter APP 最終使用的Locale
。通常在不支持的語(yǔ)言區(qū)域時(shí)返回一個(gè)默認(rèn)的Locale
。
localeListResolutionCallback
和localeResolutionCallback
唯一的不同就在第一個(gè)參數(shù)類型,前者接收的是一個(gè)Locale
列表,而后者接收的是單個(gè)Locale
。
Locale Function(List<Locale> locales, Iterable<Locale> supportedLocales)
在較新的 Android 系統(tǒng)中,用戶可以設(shè)置一個(gè)語(yǔ)言列表,這樣一來(lái),支持多語(yǔ)言的應(yīng)用就會(huì)得到這個(gè)列表,應(yīng)用通常的處理方式就是按照列表的順序依次嘗試加載相應(yīng)的 Locale,如果某一種語(yǔ)言加載成功則會(huì)停止。圖13-1是 Android 系統(tǒng)中設(shè)置語(yǔ)言列表的截圖:
在 Flutter 中,應(yīng)該優(yōu)先使用localeListResolutionCallback
,當(dāng)然你不必?fù)?dān)心 Android 系統(tǒng)的差異性,如果在低版本的 Android 系統(tǒng)中,F(xiàn)lutter 會(huì)自動(dòng)處理這種情況,這時(shí) Locale 列表只會(huì)包含一項(xiàng)。
Localizations 組件用于加載和查找應(yīng)用當(dāng)前語(yǔ)言下的本地化值或資源。應(yīng)用程序通過(guò)Localizations.of(context,type)
(opens new window)來(lái)引用這些對(duì)象。 如果設(shè)備的 Locale 區(qū)域設(shè)置發(fā)生更改,則 Localizations 組件會(huì)自動(dòng)加載新區(qū)域的 Locale 值,然后重新 build 使用(依賴)了它們的組件,之所以會(huì)這樣,是因?yàn)?code>Localizations內(nèi)部使用了InheritedWidget (opens new window),我們?cè)诮榻B該組件時(shí)講過(guò):當(dāng)子組件的build
函數(shù)引用了InheritedWidget
時(shí),會(huì)創(chuàng)建對(duì)InheritedWidget
的隱式依賴關(guān)系。因此,當(dāng)InheritedWidget
發(fā)生更改時(shí),即Localizations
的 Locale 設(shè)置發(fā)生更改時(shí),將重建所有依賴它的子組件。
本地化值由Localizations
的 LocalizationsDelegates (opens new window)列表加載 。 每個(gè)委托必須定義一個(gè)異步 load() 方法,以生成封裝了一系列本地化值的對(duì)象。通常這些對(duì)象為每個(gè)本地化值定義一個(gè)方法。
在大型應(yīng)用程序中,不同模塊或 Package 可能會(huì)與自己的本地化值捆綁在一起。 這就是為什么要用Localizations
管理對(duì)象表的原因。 要使用由LocalizationsDelegate
的load
方法之一產(chǎn)生的對(duì)象,可以指定一個(gè)BuildContext
和對(duì)象的類型來(lái)找到它。例如,Material 組件庫(kù)的本地化字符串由MaterialLocalizations (opens new window)類定義,此類的實(shí)例由 MaterialApp (opens new window)類提供的LocalizationDelegate
創(chuàng)建, 它們可以如下方式獲取到:
Localizations.of<MaterialLocalizations>(context, MaterialLocalizations);
這個(gè)特殊的Localizations.of()
表達(dá)式會(huì)經(jīng)常使用,所以 MaterialLocalizations 類提供了一個(gè)便捷方法:
static MaterialLocalizations of(BuildContext context) {
return Localizations.of<MaterialLocalizations>(context, MaterialLocalizations);
}
// 可以直接調(diào)用便捷方法
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
為了盡可能小而且簡(jiǎn)單,flutter 軟件包中僅提供美國(guó)英語(yǔ)值的MaterialLocalizations
和WidgetsLocalizations
接口的實(shí)現(xiàn)。 這些實(shí)現(xiàn)類分別稱為DefaultMaterialLocalizations
和DefaultWidgetsLocalizations
。flutter_localizations 包包含GlobalMaterialLocalizations
和GlobalWidgetsLocalizations
的本地化接口的多語(yǔ)言實(shí)現(xiàn), 國(guó)際化的應(yīng)用程序必須按照本節(jié)開(kāi)頭說(shuō)明的那樣為這些類指定本地化 Delegate。
上述的GlobalMaterialLocalizations
和GlobalWidgetsLocalizations
只是 Material 組件庫(kù)的本地化實(shí)現(xiàn),如果我們要讓自己的布局支持多語(yǔ)言,那么就需要實(shí)現(xiàn)在即的Localizations
,我們將在下一節(jié)介紹其具體的實(shí)現(xiàn)方式。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: