Я создаю приложение с Flutter и у меня возникла проблема с использованием FutureBuilder. Ситуация такова, что моя HomePage в приложении должна сделать запрос на мой сервер и получить Json. Вызов метода getData происходит в методе сборки Homescreen (не уверен, правильно ли это).
Следующий вызов в методе сборки имеет моментальный снимок и создает ListView.
Вот проблема:
Каждый раз, когда я нажимаю кнопку или перехожу на другой экран, Future Builder срабатывает! Это означает, что у меня есть куча бесполезных вызовов API.
Вот вопрос:
Что мне нужно изменить, чтобы позволить Future Builder запускаться только когда я прихожу на главный экран?
class HomeState extends State<Home> {
int count = 0;
final homeScaffoldKey = GlobalKey<ScaffoldState>();
List compList = new List();
Future<List> getData() async {
final response = await http.get(
Uri.encodeFull("http://10.0.2.2:5000/foruser"),
headers: {
"Authorization":
"JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NTk2NDM4ODcsImlhdCI6MTU1NzA1MTg4NywibmJmIjoxNTU3MDUxODg3LCJpZGVudGl0eSI6MX0.OhuUgX9IIYFX7u0o_6MXlrMYwk7oMCywlmHLw-vbNSY",
"charset": "utf-8"
},
);
if (response.statusCode == 200) {
compList = jsonDecode(response.body);
List<Comp> result = [];
count++;
for (var c in compList) {
Comp comp = Comp.fromJson(c);
result.add(comp);
}
return result;
} else {
throw Exception('Failed to load');
}
}
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.white10,
body: Stack(
children: <Widget>[
new Container(
child: FutureBuilder(
future: getData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return new Container(
child: Text("whoops"),
);
}
if (snapshot.hasData) {
if (snapshot.data != null) {
if (snapshot.data.toString() == "[]") {
print("no comps - called API: $count");
return new ListView(
key: Key("1"),
children: <Widget>[
new Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(
height: 30.0,
),
Card(
color: Colors.blue,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text(
"Welcome, you have no comps",
style:
TextStyle(color: Colors.white),
),
),
],
),
),
],
),
],
);
}
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
print(index);
if (index == 0) {
return new Column(
children: <Widget>[
Card(
color: Colors.blue,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text(
"Welcome back, these are your comps",
style:
TextStyle(color: Colors.white),
),
),
],
),
),
SizedBox(
height: 10.0,
),
new CompListItem(
new Comp(
snapshot.data[index].left_name,
snapshot.data[index].right_name,
snapshot.data[index].left,
snapshot.data[index].right,
snapshot.data[index].left_city,
snapshot.data[index].right_city,
snapshot.data[index].latitude_left,
snapshot.data[index].longitude_left,
snapshot.data[index].latitude_right,
snapshot.data[index].longitude_right,
snapshot.data[index].points,
),
"left")
],
);
}
Comp tmp = new Comp(
snapshot.data[index].left_name,
snapshot.data[index].right_name,
snapshot.data[index].left,
snapshot.data[index].right,
snapshot.data[index].left_city,
snapshot.data[index].right_city,
snapshot.data[index].latitude_left,
snapshot.data[index].longitude_left,
snapshot.data[index].latitude_right,
snapshot.data[index].longitude_right,
snapshot.data[index].points,
);
return new CompListItem(tmp, "left");
},
);
} else if (snapshot.data == null) {
return new Container(
child: Text("Sorry, there seems to be a problem :("),
);
}
}
} else {
return CircularProgressIndicator();
}
},
),
),
],
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
FloatingActionButton(
heroTag: null,
child: Icon(
Icons.add_location,
color: Colors.white,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MakeComp(),
),
);
},
backgroundColor: Colors.blue,
),
SizedBox(
height: 10.0,
),
FloatingActionButton(
heroTag: null,
child: Icon(Icons.compare_arrows),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => GetComps(),
),
);
},
backgroundColor: Colors.blue,
),
],
));
}
}
Фактические результаты:
Откройте приложение -> Запуски Future Builder -> Отображается список данных -> Перейдите к другому виджету -> Запускается Future Builder -> нажмите кнопку -> Запускается Future Builder
Ожидаемые результаты:
Откройте приложение -> Запуски Future Builder -> Отображается список данных -> Перейдите к другому виджету -> нажмите на какую-нибудь кнопку -> сделать что-нибудь на другом экране -> вернуться на домашний экран -> Запускается Future Builder