Flutter(9)-i18n的国际化使用和Provider的简
2019-10-23 本文已影响0人
BoxJing
本篇文章介绍介绍一下,在Flutter中如何使用i18n来进行国际化和用Provider来简单的进行状态管理。
1. i18n国际化
开发工具使用Android Studio,如图在Preferences
->Plugins
中搜索i18n
进行插件安装,安装完后,新建的flutter项目会自带i18n.dart
和arb
文件。
在res
->values
中我们可以新建需要支持的国家的Arb
文件。
然后我们就可以在对应的
arb
文件中,写对应的键值对,和iOS的国际化一毛一样。添加key-value.jpg
在
i18n.dart
的文件中已经说明该文件完全自动生成的,用户的更改会被放弃,我们会发现我们修改了arb
的键值对后,i18n文件会自动生成一些代码,完全不用我们再去更改,也不允许我们更改。i18n文件.jpg
然后我们需要在MaterialApp里面使用
localeResolutionCallback: (Locale locale, Iterable<Locale> supported)
这个回调拿到当前系统的语言,然后返回对应的国际化语言,里面需要返回一个对应的Local
对象,当返现我们APP内没有对应的国际化的时候,就需要我们返回一个合适的存在的Local
对象。
localeResolutionCallback: (Locale locale, Iterable<Locale> supported) {
bool isSupported(Locale locale) {
if (locale == null) return false;
if (supported.contains(locale)) {
return true;
} else {
for (Locale supportedLocale in supported) {
if (supportedLocale.countryCode == null || supportedLocale.countryCode.isEmpty)
if (supportedLocale.languageCode == locale.languageCode) return true;
}
return false;
}
}
if (!isSupported(locale))
return supported.first;
final Locale languageLocale = Locale(locale.languageCode, "");
if (supported.contains(locale)) return locale;
else if (supported.contains(languageLocale)) return languageLocale;
else return supported.first;
},
在对应的地方取值S.of(context).app_information
,可能你会发现没跟着系统走,对应的平台工程需要设置一下语言的支持,iOS如下:
到此,使用i18n插件根据系统语言进行国际化就完成了。
2. Provider
在pubsepec.yaml
中添加provider: ^3.1.0
,然后packages get
添加provider的引入,provider
作为谷歌的亲儿子,使用起来也觉得挺方便,在开发的过程中可以替代掉stateless
类型的Widget,根据需要进行刷新。
新建一个类作为数字的管理类,在需要通知刷新的地方调用notifyListeners()
:
import 'package:flutter/cupertino.dart';
class BoxProvider extends ChangeNotifier {
int _index = 0;
void setIndex(int index) {
if (_index != index) {
_index = index;
debugPrint('通知刷新');
notifyListeners();
}
}
int index () {
return _index;
}
void changeIndex() {
debugPrint('改变');
setIndex(_index+1);
}
}
由于需要跨界面来实现,所以我们需要在顶层进行Provider的注册:
MultiProvider(
providers:[
ChangeNotifierProvider<BoxProvider>(
builder: (context) => BoxProvider(),
),
],
child: MaterialApp(
...
然后在需要更新的地方进行Consumer
,在收到notifyListeners()
之后,此处会重新builder
来构建界面:
Consumer<BoxProvider>(
builder: (context,model,_){
return Text(
model.index().toString(),
);
},
),
注册在顶层,这样的话我们可以在任何的一个页面进行改变的操作:
Provider.of<BoxProvider>(context).changeIndex();
看一下效果:
小Demo源码已经放在Github: i18n&Provider中。