即使基本的未来都没有改变,如何防止FutureBuilder的重建

问题描述 投票:1回答:1

在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);
    }
  }
}
dart flutter
1个回答
0
投票

对于其他有此错误的人,我使用GitHub上的AbdulRahmanAlHamali解决方案解决了。这是他的答案:

你好,我相信这里的问题是每次发出重建文件时,都会调用FutureBuilder状态。此功能检查旧的将来对象是否与新的,如果是,则重新启动FutureBuilder。

要超越这一点,我们可以将Future称为构建功能。例如,在initState中,并将其保存在成员中变量,然后将此变量传递给FutureBuilder。

所以没有:

FutureBuilder(
  future: someFunction(),
  ....

我们应该有:

initState() {
  super.initState();
  _future = SomeFunction();
}

然后

FutureBuilder(
  future: _future,
  ....

查找原始线程here

© www.soinside.com 2019 - 2024. All rights reserved.