I'm building a weather forecast app in which SliverAppBar shows current weather and SliverList shows daily forecast in form of cards. I get data from DarkSky API as a Map.
I have completed the current weather part with FutureBuilder, but now I'm having a trouble finding how to fill SliverList. I tried to do it with FutureBuilder as well, but without success.
This is my code
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new CustomScrollView(
slivers: <Widget>[
new SliverAppBar(
brightness: Brightness.dark,
centerTitle: true,
title: Text('Weather'),
expandedHeight: 300,
floating: true,
pinned: true,
snap: true,
flexibleSpace: FlexibleSpaceBar(
background: new Container(
child: updateCurrentWeather(), //METHOD CONSTRUCTING CONTENT OF SliverAppBar
)),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Card(
margin: EdgeInsets.fromLTRB(30, 3, 30, 3),
color: Colors.black12,
child: new ListTile(
leading: Icon(Icons.watch_later),
title: new Text('$index',
style: new TextStyle(color: Colors.white)),
subtitle: new Text('29 °C'),
),
),
childCount: 20),
)
],
));
}
Future<Map> getWeather(String key, double lat, double lon) async {
String apiUrl =
'https://api.darksky.net/forecast/$key/$lat,$lon?lang=sk&units=si';
http.Response response = await http.get(apiUrl);
return json.decode(response.body);
}
How can I fill the SliverList with the map I get?
You can use this code but remember to create your data model for the network response to fill the list:
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new CustomScrollView(
slivers: <Widget>[
new SliverAppBar(
brightness: Brightness.dark,
centerTitle: true,
title: Text('Weather'),
expandedHeight: 300,
floating: true,
pinned: true,
snap: true,
flexibleSpace: FlexibleSpaceBar(
background: new Container(
child: updateCurrentWeather(), //METHOD CONSTRUCTING CONTENT OF SliverAppBar
)),
),
FutureBuilder(
future: getWeather(
"secret key", 37.8267, -122.4233),
builder: (context, projectSnap) {
// Whether project = projectSnap.data[index]; //todo check your model
var childCount = 0;
if(projectSnap.connectionState !=
ConnectionState.done || projectSnap.hasData == null)
childCount = 1;
else
childCount = projectSnap.data.length;
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (projectSnap.connectionState !=
ConnectionState.done) { //todo handle state
return CircularProgressIndicator(); //todo set progress bar
}
if (projectSnap.hasData == null) {
return Container();
}
return Card(
margin: EdgeInsets.fromLTRB(30, 3, 30, 3),
color: Colors.black12,
child: new ListTile(
leading: Icon(Icons.watch_later),
title: new Text("$index",
style: new TextStyle(color: Colors.white)),
subtitle: new Text('29 °C'), //todo set your data from response
),
);
},
childCount: childCount),
);
},
),
],
));
}
Future<Map> getWeather(String key, double lat, double lon) async {
String apiUrl =
'https://api.darksky.net/forecast/$key/$lat,$lon?lang=sk&units=si';
http.Response response = await http.get(apiUrl);
return json.decode(response.body);
}
}