Flutter International 国际化,Localization 本地化, 使用字符串Map
本文最后更新于:2019年11月1日 晚上
记录一种简单的方式实现字符串的国际化。
这里没有用到Intl
包,而是将所需的字符串存放在一个map中。
步骤:
MaterialApp
中添加本地化代理和语言类型- 创建文字资源文件
- 新建一个类继承
LocalizationsDelegate
,和文字资源文件联系起来 - 使用代理获取想要的文字资源
新建项目international_demo
,得到一个带按钮示例工程。改造一下MaterialApp
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
localizationsDelegates: [// 添加区域
// 准备在这里添加我们自己创建的代理
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [ // 添加区域
const Locale('en', 'US'), // English
const Locale('he', 'IL'), // Hebrew
// 可以继续添加我们想要支持的语言类型
],
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
创建资源文件
新建localization_src.dart
,将字符串存入一个map中。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27import 'package:flutter/material.dart';
class DemoLocalizations {
DemoLocalizations(this.locale);
final Locale locale;
static DemoLocalizations of(BuildContext context) {
return Localizations.of<DemoLocalizations>(context, DemoLocalizations);
}
static Map<String, Map<String, String>> _localizedValues = {
'en': {
'title': 'Hello World',
},
'es': {
'title': 'Hola Mundo',
},
'zh': {
'title': '你好呀',
},
};
String get title {
return _localizedValues[locale.languageCode]['title'];
}
}
这里仅以title
为例,有英语、西班牙语和中文三种。
创建代理
新建一个类继承LocalizationsDelegate
,复写3个方法。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:international_demo/localization_src.dart';
class DemoLocalizationsDelegate
extends LocalizationsDelegate<DemoLocalizations> {
const DemoLocalizationsDelegate();
@override
bool isSupported(Locale locale) =>
['en', 'es', 'zh'].contains(locale.languageCode);
@override
Future<DemoLocalizations> load(Locale locale) {
return SynchronousFuture<DemoLocalizations>(DemoLocalizations(locale));
}
@override
bool shouldReload(DemoLocalizationsDelegate old) => false;
}
复写的load方法中,使用了SynchronousFuture
。
使用代理
回到main.dart
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
localizationsDelegates: [
DemoLocalizationsDelegate(),// 这是我们新建的代理
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English
const Locale('he', 'IL'), // Hebrew
const Locale('zh', ''), // 新添中文,后面的countryCode暂时不指定
],
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
在_MyHomePageState
中调用DemoLocalizations
。1
2DemoLocalizations localizations = DemoLocalizations.of(context);
print(localizations); // 打印出 I/flutter (25535): Instance of 'DemoLocalizations'
观察logcat,可知我们获得了DemoLocalizations的实例。
获取title
1
DemoLocalizations.of(context).title
如果需要更多的字符串,需要我们手动在资源文件的map中添加。
这里仅以title为例。
参考: