Reputation: 63
When I change the state upon which a specific futurebuilder widget relies, the widget is not redrawn until the async task completes. I want the widget to be redrawn immediately once the state changes. Below is the code for the 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();
}
},
)
Upvotes: 6
Views: 9961
Reputation: 41
this a bit late but it worked for me just replace the screen with the same screen
Navigator.pushReplacement(context,
MaterialPageRoute(
builder: (BuildContext context) =>
*SamePage*()
)
);
don't use this method inside a showdialog to avoid backing on the same page twice!
Upvotes: -1
Reputation: 277037
You can't do that using FutureBuilder. If you want to build more than "initial" + "done" don't use FutureBuilder.
Instead you can use a Stream
and StreamBuilder
by submitting your future result to the stream.
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");
}
},
);
}
}
Upvotes: 8
Reputation: 4859
I think FutureBuilder only builds once at start then everytime async task is compelted. So when we navigate to screen FutureBuilder is build at start then when async task is complete, then for other calls (except first) FutureBuilder only builds after async task is completed.
I also needed rebuild FutureBuilder at start of async call, I solved this issue by using snapshot.connectionState
Insider builder of FutureBuilder
if(snapshot.connectionState == ConnectionState.done){
if(snapshot.hasData){
//Show data here
}else{
//Show error here
}
}else{
//Show progress
}
Upvotes: 9