背景信息:
对于我的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个按钮)。
由于每个按钮都有唯一的索引,是否有办法将要重建的特定按钮作为目标,而忽略其余按钮?
谢谢!
答案 0 :(得分:1)
首先,请注意,您尝试进行的优化通常都是毫无意义的。
优化重建通常没有什么好处,并且可能不值得增加额外的复杂性,并且仅在状态以非常频繁的速度变化(例如动画)时才有用。
也就是说,您要寻找的是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
,而忽略其他任何更改。
答案 1 :(得分:-2)
您可以看到上面的代码
...
return FlatButton(
child: Text(Provider.of<mybuttons>(context).getText(buttons)),
onTap: (){
Provider.of<mybuttons>(context).changeIndex(buttonIndex);
}
);
并且mybuttons
通知程序必须具有存储按钮状态的数据结构,并且必须具有getText
和changeIndex
方法。
我只是想知道为什么不简单地使用一个有状态的小部件?