Flutter实战(二)---多语言跨平台
前言
去年12月份,Flutter1.0正式版发布,标志着Flutter已经达到可以投入商用项目的状态,我们可以看到Google的野心,不止步于移动端,已经向桌面端(Flutter Desktop Embedding)和Web端(Hummingbird)逐步拓展,大有一统天下之趋势。
时隔三月,在2019 MWC 世界移动通信大会上,Flutter1.2发布,除了UI组件更新、动画优化和Dart语言特性改进外,我们惊喜的发现,Flutter正朝着轻应用的方向迈开强有力的步伐,支持Android APP Bundles,意味着Flutter不仅支持热重载,也开始支持热更新,代码动态交付,应用体积更小。
进入正题
本文主要介绍Flutter应用国际化,通常我们新建的 Flutter 应用是默认不支持多语言的,即使用户在中文环境下,显示的文字仍然是英文,比如下图所示的日期选择对话框:
那么怎么样将系统的这些组件国际化呢?首先需要在 pubspec.yaml 中添加如下依赖:
接着运行:
以获取依赖库。
当上面两部完成后在 main.dart 中 import 如下:
import 'package:flutter_localizations/flutter_localizations.dart’;
然后在 MaterialApp 的构造方法中给 localizationsDelegates 和 supportedLocales 两个可选参数赋值:
supportedLocales: [
const Locale('zh', 'CH'),
const Locale('en', 'US'),
],
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
MyLocalizationsDelegate.delegate,
],
此时该应用已经支持中文和英文两种语言了,接下来就是字符串的翻译,我们知道Android原生多语言翻译是在对应语言的string.xml资源里配置相应的字符串,但是xml方式无法做到跨平台,那么Flutter的做法是自定义一个类似GlobalMaterialLocalizations的MyLocalizationsDelegate类来实现多语言:
- 定义一个静态Map,key为国家代号,value也是一个Map,value的map键为资源名,值为字符串
static Map<String, Map<String, String>> _localizedValues = {
'en’: {
'cancel': ‘cancel',
'confirm': ‘confirm’,
},
'zh': {
'cancel': '取消',
'confirm': '确定’,
}
}
- 为每个资源名定义get方法
get cancel {
return _localizedValues[locale.languageCode]['cancel'];
}
get confirm {
return _localizedValues[locale.languageCode]['confirm'];
}
- 定义一个静态初始化方法
static MyLocalizations of(BuildContext context) {
return Localizations.of(context, MyLocalizations);
}
- 实现delegate
class MyLocalizationsDelegate extends LocalizationsDelegate<MyLocalizations> {
const MyLocalizationsDelegate();
@override
bool isSupported(Locale locale) {
return ['en', 'zh'].contains(locale.languageCode);
}
@override
Future<MyLocalizations> load(Locale locale) {
return new SynchronousFuture<MyLocalizations>(new MyLocalizations(locale));
}
@override
bool shouldReload(LocalizationsDelegate<MyLocalizations> old) {
return false;
}
static MyLocalizationsDelegate delegate = const MyLocalizationsDelegate();
}
- 使用方法
label: new Text(MyLocalizations.of(context).cancel),
至此,Flutter多语言问题就解决了。