Flutter Provider:针对特定目标的 notifyListeners()
Flutter Provider: notifyListeners() to specific target
背景资料:
对于我的 flutter 项目,我使用 listview.builder
和 provider
:
ListView.Builder
:使用提供商获取 buttons
信息,listen
是 false
。
@override
Widget build(BuildContext context) {
final buttons = Provider.of<mybuttons>(context, listen: false);
return Container(
child: ListView.builder(
itemCount: buttons.length,
itemBuilder: (context, index) {
return singleButton(listIndex: index);
},
),
);
}
然后... 其中,singleButton()
:这将 运行 根据来自父小部件的 length
。
@override
Widget build(BuildContext context) {
final singleButtonInfo = Provider.of<mybuttons>(context).buttonIndex[listIndex];
return FlatButton(
child: Text(singleButtonInfo.text),
onTap: (){
changeText(listIndex);
}
);
}
因此,如果length
是5,那么就会有5个索引从0到4的平面按钮。
使用 onTap
函数,我想更改该特定按钮的文本(即,如果单击第 3 个按钮,那么我只想更改第 3 个按钮而不重建所有按钮)。
changeText(int listIndex){
...logic
notifyListeners();
}
这里是问题:
我对 notifyListeners()
的理解是,它将通过 Provider.of<T>(context)
通知所有内容,并且将重建那些小部件(即所有 5 个按钮都将使用新数据重建)。
因为每个按钮都有一个唯一的索引,有没有办法针对要重建的特定按钮并忽略其余按钮?
谢谢!
可以看到上面的代码
...
return FlatButton(
child: Text(Provider.of<mybuttons>(context).getText(buttons)),
onTap: (){
Provider.of<mybuttons>(context).changeIndex(buttonIndex);
}
);
并且 mybuttons
通知程序必须具有存储按钮状态的数据结构并且必须具有 getText
和 changeIndex
方法。
我只是想知道你为什么不简单一个有状态的小部件?
首先,请注意,您尝试进行的优化在大多数情况下是毫无意义的。
优化重建通常没有什么好处,可能不值得增加复杂性,并且只有在状态以非常频繁的速率变化(如动画)时才有用。
也就是说,您要查找的是 Selector。
Selector 是消费提供者的习惯,与 Consumer/Provider.of 相对,有办法过滤不需要的更新。
例如,如果一个小部件只需要 MyModel.text
,那么代替:
final model = Provider.of<MyModel>(context);
return Text(model.text);
我们可以这样使用 Selector:
return Selector<MyModel, String>(
selector: (_, model) => model.text,
builder: (_, text, __) {
return Text(text);
}
);
这样的代码将再次调用 builder
仅当 MyModel.text
发生变化时 ,并忽略任何其他变化。
背景资料:
对于我的 flutter 项目,我使用 listview.builder
和 provider
:
ListView.Builder
:使用提供商获取 buttons
信息,listen
是 false
。
@override
Widget build(BuildContext context) {
final buttons = Provider.of<mybuttons>(context, listen: false);
return Container(
child: ListView.builder(
itemCount: buttons.length,
itemBuilder: (context, index) {
return singleButton(listIndex: index);
},
),
);
}
然后... 其中,singleButton()
:这将 运行 根据来自父小部件的 length
。
@override
Widget build(BuildContext context) {
final singleButtonInfo = Provider.of<mybuttons>(context).buttonIndex[listIndex];
return FlatButton(
child: Text(singleButtonInfo.text),
onTap: (){
changeText(listIndex);
}
);
}
因此,如果length
是5,那么就会有5个索引从0到4的平面按钮。
使用 onTap
函数,我想更改该特定按钮的文本(即,如果单击第 3 个按钮,那么我只想更改第 3 个按钮而不重建所有按钮)。
changeText(int listIndex){
...logic
notifyListeners();
}
这里是问题:
我对 notifyListeners()
的理解是,它将通过 Provider.of<T>(context)
通知所有内容,并且将重建那些小部件(即所有 5 个按钮都将使用新数据重建)。
因为每个按钮都有一个唯一的索引,有没有办法针对要重建的特定按钮并忽略其余按钮?
谢谢!
可以看到上面的代码
...
return FlatButton(
child: Text(Provider.of<mybuttons>(context).getText(buttons)),
onTap: (){
Provider.of<mybuttons>(context).changeIndex(buttonIndex);
}
);
并且 mybuttons
通知程序必须具有存储按钮状态的数据结构并且必须具有 getText
和 changeIndex
方法。
我只是想知道你为什么不简单一个有状态的小部件?
首先,请注意,您尝试进行的优化在大多数情况下是毫无意义的。
优化重建通常没有什么好处,可能不值得增加复杂性,并且只有在状态以非常频繁的速率变化(如动画)时才有用。
也就是说,您要查找的是 Selector。
Selector 是消费提供者的习惯,与 Consumer/Provider.of 相对,有办法过滤不需要的更新。
例如,如果一个小部件只需要 MyModel.text
,那么代替:
final model = Provider.of<MyModel>(context);
return Text(model.text);
我们可以这样使用 Selector:
return Selector<MyModel, String>(
selector: (_, model) => model.text,
builder: (_, text, __) {
return Text(text);
}
);
这样的代码将再次调用 builder
仅当 MyModel.text
发生变化时 ,并忽略任何其他变化。