当状态改变时,如何强制立即重绘futurebuilder?

Mar*_*don 5 flutter

当我更改特定 futurebuilder 小部件所依赖的状态时,该小部件在异步任务完成之前不会重绘。我希望在状态发生变化后立即重新绘制小部件。下面是futurebuilder的代码:

child: new FutureBuilder(
            future: _api.getListOfTourneys(searchTerm, filterChecks, pageNum),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                if(!(snapshot.data is List)){
                  return new TourneyItem(snapshot.data['tournament']);
                }
                return new Expanded(
                    child: ListView.builder(
                  shrinkWrap: false,
                  scrollDirection: Axis.vertical,
                  itemCount: snapshot.data.length,
                  itemBuilder: (BuildContext context, int index) {
                    return TourneyItem(snapshot.data[index]);
                  },
                ));
              } else if (snapshot.hasError) {
                return new Text("No results found");
              } else {
                return new CircularProgressIndicator();
              }
            },
          )
Run Code Online (Sandbox Code Playgroud)

Dhi*_*rma 7

我认为 FutureBuilder 只在开始时构建一次,然后每次异步任务都被强制执行。因此,当我们导航到屏幕 FutureBuilder 在开始时构建然后异步任务完成时,然后对于其他调用(除了第一个)FutureBuilder 仅在异步任务完成后构建。

我还需要在异步调用开始时重建 FutureBuilder,我通过使用解决了这个问题 snapshot.connectionState

FutureBuilder的内幕建造者

if(snapshot.connectionState == ConnectionState.done){
    if(snapshot.hasData){
        //Show data here
    }else{
       //Show error here
    }
}else{
    //Show progress
}
Run Code Online (Sandbox Code Playgroud)


Rém*_*let 7

你不能用 FutureBuilder 做到这一点。如果您想构建的不仅仅是“初始”+“完成”,请不要使用 FutureBuilder。

相反,您可以通过将您未来的结果提交到流来使用StreamStreamBuilder

class Foo extends StatefulWidget {
  @override
  _FooState createState() => _FooState();
}

class _FooState extends State<Foo> {
  StreamController streamController;

  @override
  void initState() {
    load();
    super.initState();
  }

  load() async {
    streamController.add("Loading");
    await Future.delayed(Duration(seconds: 1));
    streamController.add("Done");
  }

  @override
  void didUpdateWidget(Foo oldWidget) {
    if (somethingChanged) {
      load();
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
    void dispose() {
      streamController.close();
      super.dispose();
    }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<String>(
      stream: streamController.stream,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return new Text(snapshot.data);
        } else if (snapshot.hasError) {
          return new Text("Error");
        } else {
          return new Text("Nothing");
        }
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)