学习Flutter一段时间了,偶然看到大家都说状态管理,多数人都是用redux,对于一个Android开发人员来说之前根本没接触过,于是开始了解redux
,之后又了解闲鱼推出的fish_redux
,然后又看到Vadaski发表的一系列关于Flutter状态管理的文章,包括Scoped Model
, Redux
, BLoC
,RxDart
,provide
(想了解的可以移步),看的是眼花缭乱。对于Redux,能看懂是怎么写的,但真要到应用的层面,感觉还是有些吃力,更不知道怎样维护好它,一时间也不知道用什么什么适合自己。后来又接触到google推荐的Provider,于是学习了下。接下来就用Provider来实现一个计数的例子。
第一步,添加Provider依赖
provider: ^2.0.1+1
pub地址:https://pub.dev/packages/provider
第二步,创建Model
import 'package:provider/provider.dart';
class Counter with ChangeNotifier {//1
int _count;
Counter(this._count);
void add() {
_count++;
notifyListeners();//2
}
get count => _count;//3
}
简单的一个Counter
对象,里面只有一个字段_count
- 这里需要混入
ChangeNotifier
- 写一个增加的方法,然后需要调用
notifyListeners();
这个方法是通知用到Counter
对象的widget刷新用的。 -
get
方法
第三步,使用ChangeNotifierProvider
通常main()方法是这么写
main() {
runApp(MyApp());
}
我们要监听改变就要在MyApp()外面套一层,这个是全局的,于是如下
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
main() {
runApp(ChangeNotifierProvider<Counter>.value(//1
notifier: Counter(1),//2
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: "Provider",
home: HomePage(),
);
}
}
-
ChangeNotifierProvider
调用value()
方法,里面传出notifier
和child
-
notifier
设置了默认的Counter(1)
当然Provider不止提供了ChangeNotifierProvider
,还有Provider
,ListenableProvider
,ValueListenableProvider
,StreamProvider
,
具体可以看wiki.
如果想管理多个对象可以用MultiProvider
,如下
MultiProvider(
providers: [
Provider<User>.value(value: user),
Provider<Goods>.value(value: goods),
.....
],
child: someWidget,
)
第四步,使用Provider获取Counter的值
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Home"),
actions: <Widget>[
FlatButton(
child: Text("下一页"),
onPressed: () =>
Navigator.push(context, MaterialPageRoute(builder: (context) {
return SecondPage();
})),
),
],
),
body: Center(
child: Text("${Provider.of<Counter>(context).count}"),//1
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context).add();//2
},
child: Icon(Icons.add),
),
);
}
}
- 用
Provider.of<Counter>(context).count
获取_count
的值,Provider.of<T>(context)
相当于Provider去查找它管理的Counter(1)
- 用
Provider.of<Counter>(context).add();
调用Counter()
中的add()
方法
同样第二个页面也这样写,如下
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("SecondPage"),
),
body: Center(
child: Text("${Provider.of<Counter>(context).count}"),//1
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context).add();//2
},
child: Icon(Icons.add),
),
);
}
}
这样,当每个页面都点击+号按钮时,_count
便会+1,同时通知并更新到使用它的地方。
完整代码,copy后可直接运行
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
main() {
runApp(ChangeNotifierProvider<Counter>.value(
notifier: Counter(1),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
title: "Provider",
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Home"),
actions: <Widget>[
FlatButton(
child: Text("下一页"),
onPressed: () =>
Navigator.push(context, MaterialPageRoute(builder: (context) {
return SecondPage();
})),
),
],
),
body: Center(
child: Text("${Provider.of<Counter>(context).count}"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context).add();
},
child: Icon(Icons.add),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text(Provider.of<String>(context)),
),
body: Center(
child: Text("${Provider.of<Counter>(context).count}"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context).add();
},
child: Icon(Icons.add),
),
);
}
}
class Counter with ChangeNotifier {
int _count;
Counter(this._count);
void add() {
_count++;
notifyListeners();
}
get count => _count;
}
总结
看了那么多状态管理的,个人感觉Provider还是属于简单易用的,并且是google推荐的。但感觉还需要成长,让大家认可。我这里只是一个简单的使用,有一些地方也没讲太清楚还请大家见谅,同时也希望和各位学习Flutter的同学互相交流进步。