我一直在研究如何使用刷新指示器向API发出新请求,然后在我的应用中使用数据。
现在,刷新指示器正在工作,只有新数据时才刷新数据。我觉得我忽略了事情或做错了事。有人知道吗?
我想在FutureBuilder中使用刷新指示器,但是如果这不能同时使用并且有更好的方法,那当然也可以。
我将代码保持不变,因为数据已分组。所以我没有遗漏任何可能导致画面不清楚的东西。数据按日期分组,因此我可以使用StickyHeader将项目保留在该日期下。
如果编码过多,可以删除某些内容。随时调整:-)
代码:
// Refresh key!
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
GlobalKey<RefreshIndicatorState>();
@override
Widget build(BuildContext context) {
return Scaffold(
body: RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _handleRefresh,
child: FutureBuilder(
future: _meldingen,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: Text("Loading..."),
),
);
} else {
final groupByDates = groupBy(
snapshot.data, (obj) => obj.tijd.substring(0, 10));
groupByDates.forEach((date, list) {
datums.add(date);
list.forEach((listItem) {
listItem.capcodes.forEach((items) {
capcodesList.add({
"id": "${items.id}",
"gpkr": "${items.gpkr}",
"omschrijving": "${items.omschrijving}",
});
});
listItem.voertuigen.forEach((items) {
voertuigenList.add({
"nummer": "${items.nummer}",
"type": "${items.type}",
"standplaats": "${items.standplaats}",
});
});
meldingenBijDatum.add({
"id": "${listItem.id}",
"tijd": "${listItem.tijd}",
"melding": "${listItem.melding}",
"adres": {
"straat": "${listItem.adres.straat}",
"plaats": "${listItem.adres.plaats}",
"postcode": "${listItem.adres.postcode}",
"longitude": "${listItem.adres.longitude}",
"latitude": "${listItem.adres.latitude}"
},
"voertuigen": voertuigenList,
"prio": "${listItem.prio}",
"capcodes": capcodesList
});
capcodesList = [];
voertuigenList = [];
});
mapDateMelding[date] = meldingenBijDatum;
meldingenBijDatum = [];
});
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return StickyHeader(
header: Container(
height: 50.0,
padding: EdgeInsets.only(left: 16, top: 16),
alignment: Alignment.centerLeft,
color: Theme.of(context).secondaryHeaderColor,
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
child: Text(
DateFormat.EEEE('nl')
.format(DateTime.parse(
datums[index]))
.toUpperCase(),
style: const TextStyle(
color: ThemeColors.brandweer,
fontWeight: FontWeight.bold,
)),
),
Expanded(child: SizedBox()),
Container(
margin: EdgeInsets.only(right: 15),
child: Text(
DateFormat.yMMMMd('nl')
.format(DateTime.parse(
datums[index]))
.toUpperCase(),
style: const TextStyle(
color: ThemeColors.brandweer,
fontWeight: FontWeight.bold,
)),
),
],
),
SizedBox(
height: 10.0,
child: new Center(
child: new Container(
margin:
new EdgeInsetsDirectional.only(
start: 1.0, end: 15.0),
height: 2.5,
color: Colors.red,
),
),
),
],
)),
content: Column(
children: <Widget>[
getItemsWidget(datums[index]),
],
),
);
},
itemCount: groupByDates.length,
);
}
})));
}
Widget getItemsWidget(index) {
List<Widget> itemsList = new List();
List namesString = mapDateMelding[index];
for (var i = 0; i < namesString.length; i++) {
itemsList.add(GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MeldingPage(
id: namesString[i]['id'],
tijd: namesString[i]['tijd'],
prio: namesString[i]['prio'],
melding: namesString[i]['melding'],
adres: namesString[i]['adres'],
voertuigen: namesString[i]['voertuigen'],
capcodes: namesString[i]['capcodes'])));
},
child: SingleMeldingItem(
tijd: namesString[i]['tijd'],
prio: namesString[i]['prio'],
melding: namesString[i]['melding'],
straat: namesString[i]['adres']['straat'],
plaats: namesString[i]['adres']['plaats']),
));
}
Column column = new Column(
children: itemsList,
);
return column;
}
Future<Null> _handleRefresh() async {
setState(() {
_meldingen = Meldingen.getMeldingen();
});
Completer<Null> completer = new Completer<Null>();
completer.complete();
return completer.future;
}
答案 0 :(得分:1)
我将使用StreamBuilder而不是FutureBuilder。调用Refresh方法时,应将新数据推送到StreamBuilder在Refresh Widget中使用的流。