1、首先在https://www.pub.dev/中找到provider中找到这个包
2、找provider的包,provider: ^5.0.0 引入这个包,pub get一下
3、就是编写一个类型包含要共享状态,比如购物车
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'Item.dart';
class Cart with ChangeNotifier, DiagnosticableTreeMixin {
//用于保存购物车中商品列表
final List<Item> _items=[];
//购物车中的商品的总价
double get totalPrice =>
_items.fold(0, (value, item) => value+item.count*item.price);
int get num=>
_items.length;
//将item添加到购物车。这是唯一一种能从外部改变购物车的方法
void add(Item item){
_items.add(item);
//通知监听器(订阅者),重新构建Inherited Provider,更新状态
notifyListeners();
}
/// Makes `Counter` readable inside the devtools by listing all of its properties
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(IntProperty('num', _items.length));
}
}
4、然后在跟节点是用provider给共享出来
void main() {
/*runApp(
MyApp()
);*/
runApp(
/// Providers are above [MyApp] instead of inside it, so that tests
/// can use [MyApp] while mocking the providers
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Cart()),
//Provider(create: (context) => Cart()),
],
child: MyApp(),
),
);
}
5、然后在咨询类操作共享状态的是用Provider.of
Builder(builder: (BuildContext context){
return FlatButton(
child: Text("确定"),
onPressed: () {
//添加到购物车
if(_num>0){
Provider.of<Cart>(context, listen: false).add(Item(20.0, 1));
}
//关闭对话框并返回true
Navigator.of(context).pop(true);
},
);
})
这里注意俩点:
1)不能是用context.read(context).add().因为这里是一个button不需要状态更新,所以当调用的它的时候会报错。
2)在是用Provider.of的时候的节点最好是用Builder来创建一下,因为这样就把context给带过到这个子节点了。如果没有是用Builder来构建的话,可能会出现context中没有read方法,还有如果Builder构建了,一开始可能也不会出现read方法,等一会就可以了,这个可能和AndroidStudio有点关系。
6、在消费状态的地方使用Consumer来使用状态
Positioned(
top: 0,
right: 0,
child: Consumer(
builder: (BuildContext context,Cart cart,child){
//cartNum=Provider.of<Cart>(context).num;
cartNum=context.read<Cart>().num;
print("购物车的数量是:${cartNum}");
return Visibility(
child: Container(
width: 12,
height: 12,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(3)),
child: Builder(builder: (BuildContext context){
return Text(
cartNum.toString(),
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 10,
fontWeight: FontWeight.bold),
);
}),
),
visible: cartNum > 0 ? true : false,
);
},
)
),
在这里介绍一下Consumer,Consumer 中有俩个参数,一个是builder,一个是child。builder中又有3个参数,一个是context。一个是用来包含共享状态的类我这里就是Cart。还有一个参数是child,这个child其实是Consumer里边中构建的child传过来的,Consumer中的child可以不写,直接在builder中return一个widget就可以,我是这么写的。
开始我也是走了好多弯路,最后通过俩片文章了解了Provider怎么使用,我这里也把这俩片文章贴出来,一个是库中提供的示例,一个是flutter中文章程中写的。
英文:https://pub.dev/packages/provider/example
中文:https://github.com/rrousselGit/provider/blob/master/resources/translations/zh-CN/README.md
flutter教程:https://flutter.cn/docs/development/data-and-backend/state-mgmt/simple