I have a list that displays data from an API. Each item has a Favorite button (heart icon) to add the item to your favorites. Adding to favorites works, everything is fine. But I ran into a problem. When I click on the Favorite button, a change occurs on my server, but visually nothing changes, the button does not change its state. I need to close the list page and reopen - then I will see the changes. Tell me, how can I make it so that after clicking on the button, it immediately changes its state and I do not have to reload the page?
Widget build(BuildContext context) {
if (widget.stationList != null) {
for (var i = 0; i < widget.stationList!.length; i ) {
widget.stationList![i].isFavorite
? selected.add(true)
: selected.add(false);
}
}
return MediaQuery.removePadding(
context: context,
removeTop: true,
child: ListView.separated(
separatorBuilder: (context, index) => Padding(
padding: const EdgeInsets.only(left: 44, top: 10, bottom: 10),
child: Divider(
height: 0.5,
color: constants.Colors.white.withOpacity(0.20),
),
),
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: widget.stationList!.length,
itemBuilder: (context, index) {
return CupertinoButton(
color: Colors.transparent,
padding: EdgeInsets.zero,
onPressed: () {
},
child: Row(
children: [
Expanded(
flex: 1,
child: GestureDetector(
onTap: () async {
try {
log('this');
if (selected[index]) {
log('asdasdasdasdasdasd');
await FavoritesRepository()
.removeFavoriteStation(
stationId: widget.stationList![index].id,
)
.then((value) => (value) {
setState(() {
selected[index] =
!selected.elementAt(index);
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: const Duration(seconds: 2),
backgroundColor: Colors.transparent,
elevation: 0,
content: SystemMessagesSnackBar(
message:
'Successfully removed from favorites',
textButton: null,
onPressed: () {
ScaffoldMessenger.of(context)
.removeCurrentSnackBar();
},
icon: SvgPicture.asset(
'assets/icons/approve_order.svg'),
),
),
);
});
} else {
log('asdasdasdasdasdasd');
await FavoritesRepository()
.addFavoriteStation(
stationId: widget.stationList![index].id,
)
.then((value) => (value) {
setState(() {
selected[index] =
!selected.elementAt(index);
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
duration: const Duration(seconds: 2),
backgroundColor: Colors.transparent,
elevation: 0,
content: SystemMessagesSnackBar(
message:
'Successfully added to favorites',
textButton: null,
onPressed: () {
ScaffoldMessenger.of(context)
.removeCurrentSnackBar();
},
icon: SvgPicture.asset(
'assets/icons/approve_order.svg',
),
),
),
);
});
}
} catch (_) {
log(_.toString());
}
},
child: selected.elementAt(index)
? const Icon(
Icons.favorite_rounded,
)
: const Icon(Icons.favorite_border_rounded),
),
),
],
),
);
}
),
);
}
}
CodePudding user response:
Move these:
if (widget.stationList != null) {
for (var i = 0; i < widget.stationList!.length; i ) {
widget.stationList![i].isFavorite
? selected.add(true)
: selected.add(false);
}
}
to initState
:
@override
void initState() {
super.initState();
if (widget.stationList != null) {
for (var i = 0; i < widget.stationList!.length; i ) {
widget.stationList![i].isFavorite
? selected.add(true)
: selected.add(false);
}
}
}
Every time you call setStat, because of in condition in going to regenerate initial data in selected.