新建項目露戒,得到一個示例工程。本例中使用intl包來管理文字資源捶箱。
項目地址: https://github.com/RustFisher/localization_demo
步驟:
- 添加依賴項 - intl
- 創(chuàng)建文字資源文件
- 生成
arb
文件- 新增和修改
arb
文件
- 新增和修改
- 根據(jù)
arb
生成dart
文件 - 創(chuàng)建localization代理智什,新建一個類繼承
LocalizationsDelegate
,和文字資源文件聯(lián)系起來 -
MaterialApp
中添加本地化代理和語言類型 - 使用文字資源
添加依賴項
pubspec.yaml
添加依賴項flutter_localizations
丁屎,然后運行一下flutter packages get
荠锭。
dependencies:
flutter:
sdk: flutter
# 添加下面的依賴項
flutter_localizations:
sdk: flutter
intl: 0.15.6
intl_translation: 0.16.7
編輯dart文件
新建app_strings.dart
文件。
import 'dart:async';
import 'package:intl/intl.dart';
import 'package:flutter/widgets.dart';
class AppStrings {
AppStrings(Locale locale) : _localeName = locale.toString();
final String _localeName;
static Future<AppStrings> load(Locale locale) {
return initializeMessages(locale.toString())
.then((Object _) {
return new AppStrings(locale);
});
}
static AppStrings of(BuildContext context) {
return Localizations.of<AppStrings>(context, AppStrings);
}
String title() {
return Intl.message(
'Localization Demo',
name: 'title',
desc: '應用標題',
locale: _localeName,
);
}
String click() => Intl.message(
'Click',
name: 'click',
desc: '點擊',
locale: _localeName,
);
String helloFromDemo() => Intl.message(
'Hello~',
name: 'helloFromDemo',
desc: '一句問候',
locale: _localeName,
);
}
此時initializeMessages
方法會顯示警告晨川,暫時不用管证九,生成arb文件后再添加引用。
生成arb
文件
進入項目目錄共虑,運行intl
的命令愧怜。
/e/ws/localization_demo
$ flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/l10n lib/app_strings.dart
生成l10n/intl_messages.arb
,內(nèi)容如下妈拌〗懈椋可以看出是JSON格式的文本。
{
"@@last_modified": "2018-07-15T22:13:19.218221",
"title": "Localization Demo",
"@title": {
"description": "應用標題",
"type": "text",
"placeholders": {}
},
"click": "Click",
"@click": {
"description": "點擊",
"type": "text",
"placeholders": {}
},
"helloFromDemo": "Hello~",
"@helloFromDemo": {
"description": "一句問候",
"type": "text",
"placeholders": {}
}
}
新增和修改arb
文件
前面生成了l10n/intl_messages.arb
供炎,我們可以把它當成模板。復制粘貼一下疾党,同目錄下得到intl_en.arb
和intl_zh.arb
音诫。文件名規(guī)則可以自己定。
以intl_zh.arb
為例:
{
"@@last_modified": "2018-07-15T22:13:19.218221",
"title": "國際化示例App",
"@title": {
"description": "應用標題",
"type": "text",
"placeholders": {}
},
"click": "點擊",
"@click": {
"description": "點擊",
"type": "text",
"placeholders": {}
},
"helloFromDemo": "你好呀~",
"@helloFromDemo": {
"description": "一句問候",
"type": "text",
"placeholders": {}
}
}
這里也可以把intl_messages.arb
刪掉雪位。本例保留這個文件竭钝。
根據(jù)arb
生成dart
文件
$ flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/l10n \
--no-use-deferred-loading lib/app_strings.dart lib/l10n/intl_*.arb
No @@locale or _locale field found in intl_en, assuming 'en' based on the file name.
No @@locale or _locale field found in intl_messages, assuming 'messages' based on the file name.
No @@locale or _locale field found in intl_zh, assuming 'zh' based on the file name.
暫時無視警告。
注意雹洗,Windows并不一定會識別*
通配符香罐。上面寫的intl_*.arb
,可能會遇到錯誤
FileSystemException: Cannot open file, path = 'lib/*.dart' (OS Error..
這個錯誤是系統(tǒng)拋出來的时肿”用#可以嘗試用git bash來運行命令◇Τ桑可以把那個換行轉(zhuǎn)義符號去掉旦签。
$ flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/l10n --no-use-deferred-loading lib/app_strings.dart lib/l10n/intl_*.arb
若還是不行查坪,建議參考https://github.com/dart-lang/intl_translation/issues/21,不用通配符宁炫,而是一個個生成文件偿曙。
此時在app_strings.dart
中添加對l10n/intl_messages.arb
的引用。
import 'package:localization_demo/l10n/messages_all.dart';
警告消失~
更新了arb文件后羔巢,需要重新生成dart文件望忆。
創(chuàng)建localization代理
創(chuàng)建localizations_delegate.dart
。新建AppLocalizationsDelegate
類繼承LocalizationsDelegate
竿秆,復寫方法启摄。
泛型指定為前面的AppStrings
。
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:localization_demo/app_strings.dart';
class AppLocalizationsDelegate extends LocalizationsDelegate<AppStrings> {
@override
Future<AppStrings> load(Locale locale) {
return AppStrings.load(locale);
}
@override
bool isSupported(Locale locale) =>
['zh', 'en'].contains(locale.languageCode); // 支持的類型要包含App中注冊的類型
@override
bool shouldReload(AppLocalizationsDelegate old) => false;
}
MaterialApp
中添加本地化代理和語言類型
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
localizationsDelegates: [
AppLocalizationsDelegate(), // 我們定義的代理
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [ // 支持的語言類型
const Locale('en', 'US'), // English
const Locale('zh', ''),
],
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
使用文字資源
獲取到AppStrings的實例袍辞。
AppStrings appStrings = AppStrings.of(context);
print(appStrings); // logcat: I/flutter ( 7478): Instance of 'AppStrings'
注意鞋仍,在MaterialApp中使用文字資源時,因為context的關系搅吁,要使用onGenerateTitle
威创。
onGenerateTitle: (context) {
return AppStrings.of(context).title();
},
支持語言的類型
代理isSupported
方法中的語言類型最好是和App中supportedLocales
的一致
@override
bool isSupported(Locale locale) =>
['zh', 'en'].contains(locale.languageCode);
// App中`supportedLocales`
supportedLocales: [
const Locale('en', 'US'), // English
const Locale('zh', ''),
],
否則可能出現(xiàn)獲取不到AppStrings的異常。
參考: