>背景信息:
对于我的颤振项目,我正在使用listview.builder
和provider
:
ListView.Builder
:使用提供程序和listen
获取buttons
信息是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 个按钮都将使用新数据重建(。
由于每个按钮都有一个唯一的索引,因此有没有办法针对要重建的特定按钮并忽略其余按钮?
谢谢!
首先,请注意,您尝试进行的优化在大多数情况下毫无意义。
优化重建通常没有什么好处,可能不值得增加复杂性,并且仅在状态以非常频繁的速度更改时才有用(如动画(。
也就是说,您正在寻找的是选择器。
选择器是消费提供程序的自定义可能,与 Consumer/Provider.of 相反,它有一种方法可以过滤不需要的更新。
例如,如果一个小部件只需要MyModel.text
,则代替:
final model = Provider.of<MyModel>(context);
return Text(model.text);
我们可以像这样使用选择器:
return Selector<MyModel, String>(
selector: (_, model) => model.text,
builder: (_, text, __) {
return Text(text);
}
);
此类代码仅在MyModel.text
更改时再次调用builder
,并忽略对其他任何内容的更改。
你可以看到上面的代码
...
return FlatButton(
child: Text(Provider.of<mybuttons>(context).getText(buttons)),
onTap: (){
Provider.of<mybuttons>(context).changeIndex(buttonIndex);
}
);
mybuttons
通知程序必须具有存储按钮状态的数据结构,并且必须具有getText
和changeIndex
方法。
我只是想知道你为什么不简单地一个有状态的小部件?