
建立項目,得到一個示例工程。本例中使用intl包來管理文字資源。
項目位址: https://github.com/RustFisher/localization_demo
步驟:
- 添加依賴項 - intl
- 建立文字資源檔案
- 生成
檔案arb
- 新增和修改
arb
- 新增和修改
- 根據
arb
dart
- 建立localization代理,建立一個類繼承
,和文字資源檔案聯系起來LocalizationsDelegate
-
中添加本地化代理和語言類型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
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
,内容如下。可以看出是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
arb
前面生成了
l10n/intl_messages.arb
,我們可以把它當成模闆。複制粘貼一下,同目錄下得到
intl_en.arb
和
intl_zh.arb
。檔案名規則可以自己定。
以
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
删掉。本例保留這個檔案。
arb
dart
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.
暫時無視警告。
此時在
app_strings.dart
中添加對
l10n/intl_messages.arb
的引用。
import 'package:localization_demo/l10n/messages_all.dart';
警告消失~
更新了arb檔案後,需要重新生成dart檔案。
建立localization代理
建立
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
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', ''),
],
否則可能出現擷取不到AppStrings的異常。
參考:
- https://flutter.io/tutorials/internationalization/