在Flutter中,我得到了不必要的重建。在我的情况下,我使用FutureBuilder通过获取数据库结果来显示列表,该结果是将来的结果,并且依赖于查询参数。我试图确保,如果查询参数未更改,FutureBuilder的未来也不会更改,但是每次仍会调用FutureBuilder的builder块。我如何使FutureBuilder不会在未来未改变的地方重建自身。
下面是我的代码,每次MusicList2的父窗口小部件构建,MusicList2得到重建,其FutureBuilder得到重建。
class MusicList2 extends StatefulWidget {
final MusicRowActionCallback onTapItem;
final MusicRowActionCallback onDoubleTap;
final MusicRowActionCallback onLongPressed;
final String facetName;
final String facetValue;
const MusicList2(
{Key key,
this.onTapItem,
this.onDoubleTap,
this.onLongPressed,
this.facetName,
this.facetValue}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _MusicList2State();
}
}
class _MusicList2State extends State<MusicList2> {
Future<List<Music>> loadMusicByFacet;
@override
Widget build(BuildContext context) {
return FutureBuilder<List<Music>>(
future:
loadMusicByFacet,
builder: (context, snapshot) {
if (snapshot.data == null)
return Center(child: CircularProgressIndicator(),);
return ListView.builder(
shrinkWrap: true,
key: const ValueKey<String>('music-list'),
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
final random = Random();
var i = random.nextInt(5);
return MusicRow(
avatarBgColor: colors[i],
music: snapshot.data[index],
onTap: widget.onTapItem,
onDoubleTap: widget.onDoubleTap,
onLongPressed: widget.onLongPressed,
);
},
);
},
);
}
@override
void initState() {
super.initState();
loadMusicByFacet = MusicsDatabaseRepository.get.getMusicsByFacet(widget.facetName, widget.facetValue);
}
@override
void didUpdateWidget(MusicList2 oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.facetValue != widget.facetValue || oldWidget.facetName != widget.facetName) {
loadMusicByFacet = MusicsDatabaseRepository.get.getMusicsByFacet(widget.facetName, widget.facetValue);
}
}
}
对于其他有此错误的人,我使用GitHub上的AbdulRahmanAlHamali解决方案解决了。这是他的答案:
你好,我相信这里的问题是每次发出重建文件时,都会调用FutureBuilder状态。此功能检查旧的将来对象是否与新的,如果是,则重新启动FutureBuilder。
要超越这一点,我们可以将Future称为构建功能。例如,在initState中,并将其保存在成员中变量,然后将此变量传递给FutureBuilder。
所以没有:
FutureBuilder( future: someFunction(), ....
我们应该有:
initState() { super.initState(); _future = SomeFunction(); }
然后
FutureBuilder( future: _future, ....
查找原始线程here。