前言:
Provider.of<XXX>(context).数据
Provider.of<XXX>(context).方法
ChangeNotifier:这个是真正数据(状态)存放的地方。我们自己创建的provider 是混入ChangeNotifier 的。
一 安装
在pub.dev 上搜索provider
二 在main中设置
三 使用
1 > 创建一个count_provider 类
import 'package:flutter/foundation.dart';
// 实现基于ChangeNotifier的类 内部维护一个计数
// 当计数有变化的时候,同时感知所有的监听者
class CountProvider with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
// 这里一定要通知变化
notifyListeners();
}
void reset() {
_count = 0;
notifyListeners();
}
}
2> 在 Widget build(BuildContext context) 中获取provider ,需要传入context
_countProvider = Provider.of<CountProvider>(context);
3>可以调用 操作数据
this._countProvider.increment();
this._countProvider.reset();
4 在依赖数据的widget 使用数据 数据怎会
// 现获取
_countProvider = Provider.of<CountProvider>(context);
// 再去使用
Text("${this._countProvider.count}"),
四 什么是Consumer?
使用Consumer 的话,Widget build 方法不会多次build,改变只需要改变的,实现了局部刷新。
class _ProviderSonWidgetState extends State<ProviderSonWidget> {
// var _countProvider;
@override
Widget build(BuildContext context) {
print("计数改变了,ProviderSonWidgetState 调用了build");
// _countProvider = Provider.of<CountProvider>(context);
return Consumer<CountProvider>(
builder: (context, cntProvider, child) {
return Container(
child: Text("${cntProvider.count}"),
);
},
);
}
}
Consumer 这里的builder 方法会被多次的调用,其实这样很不好,因为其内部本身不依赖provider的数据,只是改变了provider的数据,所以没有必要重新
// 这里的按钮点击之后 子组件进行加1操作
floatingActionButton: Consumer<CountProvider>(
builder: (context, cntPorvider, child) {
print("Consumer->builder被调用了");
return FloatingActionButton(
onPressed: () {
// 调用加+1操作
cntPorvider.increment();
},
child: Icon(Icons.add),
);
另外还有 Consumer2 Consumer3 Consumer4 Consumer5 Consumer6
是什么意思呢
意思是 当你Builder里面的代码依赖多个provider 提供的数据时候,可以选择对应的Consumer
class Consumer3<A, B, C> extends SingleChildStatelessWidget
return Consumer2<CountProvider, UserInfoProvider>(
builder: (context, cntProvider, userProvider, child) {
return Container(
child: Text("${cntProvider.count}---${userProvider.getUsername()}"),
);
},
);
五 Selector
Selector 也有多个 Selector2 Selector3 Selector4 Selector5 Selector6
使用selector 第一个作用可以对原有的数据进行转换 第二个作用可以设置要不要重新构建,执行builder 方法
// 这里的按钮点击之后 子组件进行加1操作
floatingActionButton: Selector<CountProvider, CountProvider>(
// 这里如果return false 的话,下面的builder 就不会再次的执行
shouldRebuild: (previous, next) => false,
builder: (context, cntPorvider, child) {
print("Consumer->builder被调用了111");
return FloatingActionButton(
onPressed: () {
// 调用加+1操作
cntPorvider.increment();
},
child: Icon(Icons.add),
);
},
selector: (ctx, cntPorvider) {
return cntPorvider;
},
)