設置一個國際化的應用(yòng)程序: the flutter_localizations package
默認情況下(xià),Flutter僅提供美(měi)國英語本地化。要添加對(duì)其他(tā)語言的支持,應用(yòng)程序必須指定其他(tā)MaterialApp屬性,并包含一個名爲的單獨包-“flutter_localizations”。 截至2017年10月,該軟件包支持15種語言。
要使用(yòng)flutter_localizations,請(qǐng)将該包作(zuò)爲依賴項添加到(dào)您的pubspec.yaml文(wén)件中:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
接下(xià)來(lái),導入flutter_localizations庫,并指定MaterialApp的localizationsDelegates和(hé)supportedLocales:
import 'package:flutter_localizations/flutter_localizations.dart';
new MaterialApp(
localizationsDelegates: [
// ... app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English
const Locale('he', 'IL'), // Hebrew
// ... other locales the app supports
],
// ...
)
基于WidgetsApp的應用(yòng)程序類似,隻是不需要GlobalMaterialLocalizations.delegate。
localizationsDelegates列表中的元素是生成本地化值集合的工(gōng)廠(chǎng)。GlobalMaterialLocalizations.delegate 爲Material Components庫提供了(le)本地化的字符串和(hé)其他(tā)值。 GlobalWidgetsLocalizations.delegate定義widget默認的文(wén)本方向,從(cóng)左到(dào)右或從(cóng)右到(dào)左。
有關這(zhè)些(xiē)應用(yòng)程序屬性的更多信息,它們所依賴的類型以及如何國際化Flutter應用(yòng)程序,這(zhè)些(xiē)都可以在下(xià)面找到(dào)。
跟蹤區(qū)域設置: Locale類和(hé)Localizations widget
該Locale類是用(yòng)來(lái)識别用(yòng)戶的語言環境。 移動設備支持通過系統設置菜單爲所有應用(yòng)程序設置區(qū)域。國際化應用(yòng)程序通過顯示區(qū)域設置特定的值進行響應。 例如,如果用(yòng)戶将設備的語言環境從(cóng)英語切換到(dào)法語,則顯示“Hello World”的文(wén)本widget将用(yòng)“Bonjour le monde”重建。
Localizations小(xiǎo)部件定義其子項的區(qū)域設置以及子項依賴的本地化資源。 如果系統的語言環境發生變化,WidgetsApp将創建一個Localizations widget并重建它。
您始終可以通過以下(xià)方式查找應用(yòng)的當前區(qū)域設置:
Locale myLocale = Localizations.localeOf(context);
加載和(hé)獲取本地化的值
Localizations widget用(yòng)于加載和(hé)查找包含本地化值的集合的對(duì)象。應用(yòng)程序通過Localizations.of(context,type)來(lái)引用(yòng)這(zhè)些(xiē)對(duì)象。 如果設備的區(qū)域設置發生更改,則Localizations widget會(huì)自(zì)動加載新區(qū)域設置的值,然後重新構建使用(yòng)它們的widget。 發生這(zhè)種情況是因爲Localizations像InheritedWidget一樣工(gōng)作(zuò) 。 當build函數引用(yòng)了(le)繼承的widget時(shí),會(huì)創建對(duì)繼承的widget的隐式依賴關系。當繼承的widget發生更改(Localizations widget的區(qū)域設置發生更改時(shí)),将重建其依賴的上(shàng)下(xià)文(wén)。
本地化值由Localizations widget的 LocalizationsDelegates 列表加載 。 每個委托必須定義一個異步load() 方法,以生成封裝了(le)一系列本地化值的對(duì)象。通常這(zhè)些(xiē)對(duì)象爲每個本地化值定義一個方法。
在大(dà)型應用(yòng)程序中,不同的模塊或軟件包可能(néng)會(huì)與自(zì)己的本地化捆綁在一起。 這(zhè)就是Localizations widget管理(lǐ)對(duì)象表的原因,每個LocalizationsDelegate都有一個(對(duì)象表)。 要檢索由LocalizationsDelegateload方法之一産生的對(duì)象,可以指定一個BuildContext和(hé)對(duì)象的類型。
例如,Material Component widgets的本地化字符串由MaterialLocalizations類定義。 此類的實例由MaterialApp類提供的LocalizationDelegate創建。 它們可以通過Localizations.of被獲取到(dào):
Localizations.of
這(zhè)個特殊的Localizations.of()表達式經常使用(yòng),所以MaterialLocalizations類提供了(le)一個方便的簡寫:
static MaterialLocalizations of(BuildContext context) {
return Localizations.of
}
/// References to the localized values defined by MaterialLocalizations
/// are typically written like this:
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
使用(yòng)打包好(hǎo)的LocalizationsDelegates
爲了(le)盡可能(néng)小(xiǎo)而且簡單,flutter軟件包中僅提供美(měi)國英語值的MaterialLocalizations和(hé)WidgetsLocalizations接口的實現(xiàn)。 這(zhè)些(xiē)實現(xiàn)類分别稱爲DefaultMaterialLocalizations和(hé)DefaultWidgetsLocalizations。 除非與應用(yòng)程序的localizationsDelegates參數指定了(le)相同基本類型的不同delegate,否則它們會(huì)自(zì)動包含 。
flutter_localizations軟件包包含稱爲GlobalMaterialLocalizations和(hé)GlobalWidgetsLocalizations的本地化接口的多語言實現(xiàn)。 國際化的應用(yòng)程序必須按照設置國際化應用(yòng)程序中的說明(míng)爲這(zhè)些(xiē)類指定本地化代理(lǐ) 。
import 'package:flutter_localizations/flutter_localizations.dart';
new MaterialApp(
localizationsDelegates: [
// ... app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English
const Locale('fr', 'CA'), // canadian French
// ... other locales the app supports
],
// ...
)
全局本地化delegates構造相應類的特定于語言環境的實例。例如,GlobalMaterialLocalizations.delegate是一個産生GlobalMaterialLocalizations實例的LocalizationsDelegate。
截至2017年10月,國際化代理(lǐ)的類支持約15種語言
爲應用(yòng)的本地化資源定義一個類
将所有這(zhè)些(xiē)放(fàng)在一起用(yòng)于國際化應用(yòng)程序通常從(cóng)封裝應用(yòng)程序本地化值的類開(kāi)始。下(xià)面的例子是這(zhè)些(xiē)類的典型例子。
這(zhè)個示例的完整源代碼
本示例基于intl包提供的API和(hé)工(gōng)具 。指定本地化資源的另一個類描述了(le)一個不依賴于intl包的示例。
DemoLocalizations類包含應用(yòng)程序的字符串(僅用(yòng)于示例),該字符串被翻譯爲應用(yòng)程序支持的語言環境。 使用(yòng)Dart的intl 包生成的函數initializeMessages()來(lái)加載翻譯的字符串,并使用(yòng)Intl.message()查找它們。
class DemoLocalizations {
static Future
final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
final String localeName = Intl.canonicalizedLocale(name);
return initializeMessages(localeName).then((Null _) {
Intl.defaultLocale = localeName;
return new DemoLocalizations();
});
}
static DemoLocalizations of(BuildContext context) {
return Localizations.of
}
String get title {
return Intl.message(
'Hello World',
name: 'title',
desc: 'Title for the Demo application',
);
}
}
基于intl包的類導入生成的message目錄,該目錄提供initializeMessages()函數和(hé)每個語言環境的後備存儲Intl.message()。 message目錄由一個intl工(gōng)具生成,該工(gōng)具分析包含Intl.message()調用(yòng)的類的源代碼。在這(zhè)個示例中,這(zhè)是DemoLocalizations類。
指定應用(yòng)程序的supportedLocales參數
雖然Flutter的Material Components library包含對(duì)大(dà)約16種語言的支持,但(dàn)默認情況下(xià)僅提供英文(wén)。 開(kāi)發人員需要決定支持哪種語言,因爲工(gōng)具庫支持與應用(yòng)程序不同的一組語言環境是沒有意義的。
MaterialAppsupportedLocales參數限制語言環境更改。 當用(yòng)戶更改其設備上(shàng)的區(qū)域設置時(shí),新區(qū)域如果是列表的成員,則應用(yòng)程序的Localizations widget 就适用(yòng)于該區(qū)域。如 果找不到(dào)設備區(qū)域設置的精确匹配項(譯者語:指語言和(hé)地區(qū)同時(shí)匹配,如中文(wén),中國),則使用(yòng)第一個匹配區(qū)域設置languageCode(譯者語:隻設置語言,而不指定地區(qū))。 如果失敗,則supportedLocales使用(yòng)列表的第一個元素 。
就之前的DemoApp示例而言,該應用(yòng)隻接受美(měi)國英語或加拿大(dà)法語語言環境,并将美(měi)國英語(列表中的第一個語言環境)替換爲其他(tā)任何内容。
可以提供一個localeResolutionCallback,在應用(yòng)獲取用(yòng)戶設置的語言區(qū)域時(shí)會(huì)被回調。 例如,要讓您的應用(yòng)程序無條件接受用(yòng)戶選擇的任何區(qū)域設置:
class DemoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
localeResolutionCallback(Locale locale, Iterable
return locale;
}
// ...
);
}
}
指定本地化資源的另一個類
之前的DemoApp示例是根據Dartintl包定義的。爲了(le)簡單起見,開(kāi)發人員可以選擇自(zì)己的方法來(lái)管理(lǐ)本地化值,也(yě)可以與不同的i18n框架進行集成。 這(zhè)個示例的完整源代碼
在此版本的DemoApp中,包含應用(yòng)程序本地化的類DemoLocalizations将直接在每種語言Map中包含其所有的翻譯:
class DemoLocalizations {
DemoLocalizations(this.locale);
final Locale locale;
static DemoLocalizations of(BuildContext context) {
return Localizations.of
}
static Map
'en': {
'title': 'Hello World',
},
'es': {
'title': 'Hola Mundo',
},
};
String get title {
return _localizedValues[locale.languageCode]['title'];
}
}
在簡單的國際化應用(yòng)中, DemoLocalizationsDelegate略有不同。它的load方法返回一個SynchronousFuture, 因爲不需要進行異步加載。
class DemoLocalizationsDelegate extends LocalizationsDelegate
const DemoLocalizationsDelegate();
@override
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
@override
Future
return new SynchronousFuture
}
@override
bool shouldReload(DemoLocalizationsDelegate old) => false;
}
附錄: 使用(yòng)Dart intl工(gōng)具
在使用(yòng)Dart intl包構建API之前, 您需要查看(kàn)intl包的文(wén)檔。以下(xià)是根據intl軟件包本地化應用(yòng)程序的過程摘要。
示例程序依賴于一個生成的源文(wén)件l10n/messages_all.dart ,它定義了(le)應用(yòng)程序使用(yòng)的所有本地化字符串。
重新構建 l10n/messages_all.dart 需要兩個步驟.
将應用(yòng)程序的根目錄作(zuò)爲當前目錄,從(cóng)lib/main.dart生成l10n/intl_messages.arb
$ flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/i10n lib/main.dart
該intl_messages.arb文(wén)件是一個JSON格式的map,擁有一個在main.dart中定義的Intl.message()函數入口。 此文(wén)件作(zuò)爲英語和(hé)西班牙語翻譯的一個模闆,intl_en.arb和(hé)intl_es.arb。這(zhè)些(xiē)翻譯是由您,開(kāi)發人員創建的。
使用(yòng)應用(yòng)程序的根目錄作(zuò)爲當前目錄,爲每個intl_
$ flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/l10n \
--no-use-deferred-loading lib/main.dart lib/l10n/intl_*.arb
DemoLocalizations類使用(yòng)生成的initializeMessages() 函數(定義在intl_messages_all.dart)來(lái)加載本地化的message并使用(yòng)Intl.message()來(lái)查找它們。
網站(zhàn)建設開(kāi)發|APP設計(jì)開(kāi)發|小(xiǎo)程序建設開(kāi)發