问题
I am loading data when widget is loading like the code below. Once the UI is fully loaded, I like to add one refresh button to reload the data again.
How can I refresh the view ?
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
var futureBuilder = new FutureBuilder(
future: _getData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
return new Text('loading...');
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return createListView(context, snapshot);
}
},
);
return new Scaffold(
appBar: new AppBar(
title: new Text("Home Page"),
),
body: futureBuilder,
);
}
Future<List<String>> _getData() async {
var values = new List<String>();
await new Future.delayed(new Duration(seconds: 5));
return values;
}
Widget createListView(BuildContext context, AsyncSnapshot snapshot) {
}
}
回答1:
Widget createListView(BuildContext context, AsyncSnapshot snapshot) {
RaisedButton button = RaisedButton(onPressed: () {
setState(() {});
}, child: Text('Refresh'),);
//.. here create widget with snapshot data and with necessary button
}
回答2:
I did a deep dive into this and it's not that difficult. The builder is properly rebuilt on changing the future (if you trigger the change with setState
). Problem is, the hasData
and hasError
aren't reset until the response is back. But we can use connectionState
instead.
final builder = FutureBuilder(
future: _future,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return _buildLoader();
}
if (snapshot.hasError) {
return _buildError();
}
if (snapshot.hasData) {
return _buildDataView();
}
return _buildNoData();
});
Here's a post on the issue and a linked repo showing the issue and solution: https://www.greycastle.se/reloading-future-with-flutter-futurebuilder/
回答3:
You can refresh widget by clicking on FlatButton. The code is below.
class _MyHomePageState extends State<MyHomePage> {
String display;
Widget futureBuilder() {
return new FutureBuilder<String>(builder: (context, snapshot) {
// if(snapshot.hasData){return new Text(display);} //does not display updated text
if (display != null) {
return new Text(display);
// return your createListView(context, snapshot);
}
return new Text("no data yet");
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Home Page"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(onPressed: () async{
result = await _getData();
print(result);
// Result will be your json response
setState(() {
display = result; //assign any string value from result to display variable.
});
},
child: new Text("Get Data")
),
futureBuilder()
],
),
),
);
}
Future<List<String>> _getData() async {
var values = new List<String>();
await new Future.delayed(new Duration(seconds: 5));
return values;
}
Widget createListView(BuildContext context, AsyncSnapshot snapshot) {
}
}
来源:https://stackoverflow.com/questions/53170330/reload-data-when-using-futurebuilder