- 类
Provider
只暴露值,不触发任何rebuild
(不会通知监听者),对于Provider
,context.read()
和context.watch()
没有什么区别。
class MyModel {
var num1 = 0;
var num2 = 1;
}
// ...
@override
Widget build(BuildContext context) {
return Provider(
create: ((context) {
return MyModel();
}),
builder: (context, child) {
return Text('${context.read<MyModel>().num1} and ${context.read<MyModel>().num2}');
},
);
}
- 如果需要监听值的改变,使用
ChangeNotifierProvider
,并在其builder
中使用值的地方使用context.watch()
获取值。如果使用context.read()
,值改变不会rebuild
。
class MyModel extends ChangeNotifier {
var num1 = 0;
var num2 = 1;
}
// ...
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: ((context) {
return MyModel();
}),
builder: (context, child) {
return Text('${context.watch<MyModel>().num1} and ${context.watch<MyModel>().num1}');
},
);
}
ChangeNotifierProvider()
的create
会创建新的Listenable
对象,在当前节点被移除时,这个对象也会被销毁。如果你的
Listenable
对象需要在节点被移除时依然存在不被销毁,那么使用ChangeNotifierProvider.value()
。
final model = MyModel();
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(
value: model,
builder: (context, child) {
return Text('${context.watch<MyModel>().num1} and ${context.watch<MyModel>().num1}');
},
);
}
- 以
ChangeNotifierProvider
为例,只要builder
中的内容足够少,那么每次值改变后rebuild
的内容越少。但如果读取ChangeNotifierProvider
的value
的地方很多,但不希望这些地方都要rebuild
,可以配合使用Consumer
。
class MyModel extends ChangeNotifier {
var num1 = 0;
var num2 = 1;
addNum2() {
num2++;
notifyListeners();
}
}
// ...
final model = MyModel();
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(
value: model,
builder: (context, child) {
return Column(
children: [
Text('${context.read<MyModel>().num1}'),
Consumer<MyModel>(builder: ((context, value, child) {
return Text('${value.num2}');
})),
ElevatedButton(
onPressed: () {
model.addNum2();
},
child: const Icon(Icons.add),
),
],
);
},
);
}