Reputation: 285
What I'm trying to do After sign in, showing HomeScreen which has a listview. This listview is showing data coming from an API. So, it takes a little bit time to load. I want to render my HomeScreen after loading is completed an my listview is full of data.
What I've already done I have an api helper class that does api works. It has a static method which is getting data for my listview and returning a list. This is my getFixtureData method.
static Future<List<Fixtures>> getFixtureData() async {
Map<String, String> queryParameters = {
'league': '78',
'next': '20',
};
http.Response response = await http.get(
getUrl('fixtures', queryParameters),
headers: requestHeaders,
);
print(response.body);
if (response.statusCode == 200) {
String data = response.body;
List<dynamic> result = jsonDecode(data)['response'];
for (int i = 0; i < result.length; i++) {
Fixtures fixture = Fixtures();
fixture.leagueID = jsonDecode(data)['response'][i]['league']['id'];
fixture.country = jsonDecode(data)['response'][i]['league']['country'];
fixture.leagueName = jsonDecode(data)['response'][i]['league']['name'];
fixture.fixtureID = jsonDecode(data)['response'][i]['fixture']['id'];
//get Odds to match with fixtures by fixtureID
await getOddsData(fixture.fixtureID);
fixture.dateTime =
DateTime.parse(jsonDecode(data)['response'][i]['fixture']['date']);
fixture.homeTeam =
jsonDecode(data)['response'][i]['teams']['home']['name'];
fixture.awayTeam =
jsonDecode(data)['response'][i]['teams']['away']['name'];
fixture.status =
jsonDecode(data)['response'][i]['fixture']['status']['long'];
fixture.homeGoals = jsonDecode(data)['response'][i]['goals']['home'];
fixture.awayGoals = jsonDecode(data)['response'][i]['goals']['away'];
fixture.htScoreHome =
jsonDecode(data)['response'][i]['score']['halftime']['home'];
fixture.htScoreAway =
jsonDecode(data)['response'][i]['score']['halftime']['away'];
fixture.ftScoreHome =
jsonDecode(data)['response'][i]['score']['fulltime']['home'];
fixture.ftScoreAway =
jsonDecode(data)['response'][i]['score']['fulltime']['away'];
if (oddsList.length > 0) {
for (int j = 0; j < oddsList.length; j++) {
if (oddsList[j].fixtureID == fixture.fixtureID) {
fixture.homeOdds = oddsList[j].homeOdds;
fixture.drawOdds = oddsList[j].drawOdds;
fixture.awayOdds = oddsList[j].awayOdds;
fixture.bookmakerName = oddsList[j].bookmakerName;
FootballApi.fixtureList.add(
fixture); // this line must be here. If there is no odds of that match, it should not be in fixtureList
}
}
}
}
} else {
print('statusCode: ' + response.statusCode.toString());
}
return FootballApi.fixtureList;
}
I'm calling this method in my stateful widget(HomeScreen) which have a listview that I feed it with the list getFixtureData method returned. I'm calling it in initState of HomeScreen. This is the relevant code.
class HomeScreen extends StatefulWidget {
static String id = 'home_screen';
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int gameIndex = 0;
String gameTitle = 'Soccer';
int selectedCategoryIndex = 0;
List<Fixtures> fixtureList = List<Fixtures>();
@override
void initState() {
// TODO: implement initState
super.initState();
getFixture();
}
Future<List<Fixtures>> getFixture() async {
fixtureList = await FootballApi.getFixtureData();
return fixtureList;
}
And this part is the where I pass the data to listview in HomeScreen.
Stack(children: [
AppListView(
matchList: FootballApi.fixtureList,
//callback function brings the matchCounter value from ListView class
onChange: (value) {
setState(() {
matchCounter = value;
});
},
finalBetList: (value) {
setState(() {
betList = value;
});
},
),
The problem is; when user signs in, he is viewing my home screen with an empty listview. After a few seconds listview is loaded. I want to render HomeScreen after my listview loaded fully. What is the best way for that?
Upvotes: 0
Views: 6966
Reputation: 7931
use FutureBuilder
widget to build widgets after getting data from async functions;
FutureBuilder<List<Fixtures>>(
future: getFixture(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Fixtures> yourResponseDataFromAsync = snapshot.data;
return AppListView(
matchList: yourResponseDataFromAsync,
//callback function brings the matchCounter value from ListView class
onChange: (value) {
setState(() {
matchCounter = value;
});
},
finalBetList: (value) {
setState(() {
betList = value;
});
},
);
}
return CircularProgressIndicator();
},
),
Upvotes: 8