W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
前面講了 Material 組件庫如何支持國際化,本節(jié)我們將介紹一下我們自己的 UI 中如何支持多語言。根據(jù)上節(jié)所述,我們需要實(shí)現(xiàn)兩個(gè)類:一個(gè)Delegate
類一個(gè)Localizations
類,下面我們通過一個(gè)實(shí)例說明。
我們已經(jīng)知道Localizations
類中主要實(shí)現(xiàn)提供了本地化值,如文本:
//Locale資源類
class DemoLocalizations {
DemoLocalizations(this.isZh);
//是否為中文
bool isZh = false;
//為了使用方便,我們定義一個(gè)靜態(tài)方法
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations);
}
//Locale相關(guān)值,title為應(yīng)用標(biāo)題
String get title {
return isZh ? "Flutter應(yīng)用" : "Flutter APP";
}
//... 其它的值
}
DemoLocalizations
中會(huì)根據(jù)當(dāng)前的語言來返回不同的文本,如title
,我們可以將所有需要支持多語言的文本都在此類中定義。DemoLocalizations
的實(shí)例將會(huì)在 Delegate 類的load
方法中創(chuàng)建。
Delegate 類的職責(zé)是在 Locale 改變時(shí)加載新的 Locale 資源,所以它有一個(gè)load
方法,Delegate 類需要繼承自LocalizationsDelegate
類,實(shí)現(xiàn)相應(yīng)的接口,示例如下:
//Locale代理類
class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> {
const DemoLocalizationsDelegate();
//是否支持某個(gè)Local
@override
bool isSupported(Locale locale) => ['en', 'zh'].contains(locale.languageCode);
// Flutter會(huì)調(diào)用此類加載相應(yīng)的Locale資源類
@override
Future<DemoLocalizations> load(Locale locale) {
print("$locale");
return SynchronousFuture<DemoLocalizations>(
DemoLocalizations(locale.languageCode == "zh")
);
}
@override
bool shouldReload(DemoLocalizationsDelegate old) => false;
}
shouldReload
的返回值決定當(dāng) Localizations 組件重新 build 時(shí),是否調(diào)用load
方法重新加載 Locale 資源。一般情況下,Locale 資源只應(yīng)該在 Locale 切換時(shí)加載一次,不需要每次在Localizations
重新 build 時(shí)都加載,所以返回false
即可??赡苡行┤藭?huì)擔(dān)心返回false
的話在 APP 啟動(dòng)后用戶再改變系統(tǒng)語言時(shí)load
方法將不會(huì)被調(diào)用,所以 Locale 資源將不會(huì)被加載。事實(shí)上,每當(dāng) Locale 改變時(shí) Flutter 都會(huì)再調(diào)用load
方法加載新的 Locale,無論shouldReload
返回true
還是false
。
和上一節(jié)中介紹的相同,我們現(xiàn)在需要先注冊(cè)DemoLocalizationsDelegate
類,然后再通過DemoLocalizations.of(context)
來動(dòng)態(tài)獲取當(dāng)前 Locale 文本。
只需要在 MaterialApp 或 WidgetsApp 的localizationsDelegates
列表中添加我們的 Delegate 實(shí)例即可完成注冊(cè):
localizationsDelegates: [
// 本地化的代理類
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
// 注冊(cè)我們的Delegate
DemoLocalizationsDelegate()
],
接下來我們可以在 Widget 中使用 Locale 值:
return Scaffold(
appBar: AppBar(
//使用Locale title
title: Text(DemoLocalizations.of(context).title),
),
... //省略無關(guān)代碼
)
這樣,當(dāng)在美國英語和中文簡體之間切換系統(tǒng)語言時(shí),APP 的標(biāo)題將會(huì)分別為“Flutter APP”和“Flutter應(yīng)用”。
本節(jié)我們通過一個(gè)簡單的示例說明了 Flutter 應(yīng)用國際化的基本過程及原理。但是上面的實(shí)例還有一個(gè)嚴(yán)重的不足就是我們需要在 DemoLocalizations 類中獲取title
時(shí)手動(dòng)的判斷當(dāng)前語言 Locale,然后返回合適的文本。試想一下,當(dāng)我們要支持的語言不是兩種而是8種甚至20幾種時(shí),如果為每個(gè)文本屬性都要分別去判斷到底是哪種 Locale 從而獲取相應(yīng)語言的文本將會(huì)是一件非常復(fù)雜的事。還有,通常情況下翻譯人員并不是開發(fā)人員,能不能像 i18n 或 l10n 標(biāo)準(zhǔn)那樣可以將翻譯單獨(dú)保存為一個(gè) arb 文件交由翻譯人員去翻譯,翻譯好之后開發(fā)人員再通過工具將 arb 文件轉(zhuǎn)為代碼。答案是肯定的!我們將在下一節(jié)介紹如何通過 Dart intl 包來實(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)系方式:
更多建議: