'How can I update the favorite icon in the News page after I remove the item in the Favorite page?
First of all, sorry for my bad English. So my problem is, I have a list of news in the News Page fetch from the api and there is a favorite/heart icon on each list. After I added one of the items in the favorite Page then unfavorited it, returning to the News Page, the previous status of the item still retains.
The question is, how can I pass the status of the item to the News Page after I unfavorited it to the Favorite Page?
Note: The Favorite and News Screen shares the NewsList class
class DisplayFavorites extends StatefulWidget {
static List<dynamic> favoriteDataList = [];
static List<String> favoriteId = [];
static bool isFavoriteScreenActive = false;
const DisplayFavorites({Key? key}) : super(key: key);
@override
State<DisplayFavorites> createState() => _DisplayFavoritesState();
}
class _DisplayFavoritesState extends State<DisplayFavorites> {
get favDataList => DisplayFavorites.favoriteDataList;
@override
Widget build(BuildContext context) {
return NewsList(
results: favDataList,
// isFavorite: _isFavorite,
);
}
}
From the news_list.dart - this is the part where the favorite icon is
final List<bool> _isNewsScreenFavorite = <bool>[];
@override
initState() {
for (var i = 0; i < widget.results.length; i++) {
_isNewsScreenFavorite.add(false);
}
super.initState();
}
....
child: IconButton(
onPressed: () {
setState(() {
if (DisplayFavorites.isFavoriteScreenActive) {
_isNewsScreenFavorite[index] =
!_isNewsScreenFavorite.elementAt(index);
DisplayFavorites.favoriteDataList
.remove(wResults);
} else {
_isNewsScreenFavorite[index] =
!_isNewsScreenFavorite.elementAt(index);
_isNewsScreenFavorite[index]
? DisplayFavorites.favoriteDataList
.add(wResults)
: DisplayFavorites.favoriteDataList
.remove(wResults);
}
//print(wResults.publishedAt);
});
},
icon: Icon(
DisplayFavorites.isFavoriteScreenActive
? Icons.favorite
: _isNewsScreenFavorite.elementAt(index)
? Icons.favorite
: Icons.favorite_border_outlined,
color: Colors.red,
size: 50,
),
This is the whole code for news_list.dart (You can check this if you don't understand the code above)
class _NewsListState extends State<NewsList> {
final List<bool> _isNewsScreenFavorite = <bool>[];
@override
initState() {
for (var i = 0; i < widget.results.length; i++) {
_isNewsScreenFavorite.add(false);
}
super.initState();
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: widget.results.length,
itemBuilder: (BuildContext context, int index) {
var wResults = widget.results.elementAt(index);
return InkWell(
splashColor: Colors.red,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DisplaySelectedNews(
urlToImage: wResults.urlToImage,
author: wResults.author,
description: wResults.description,
publishedAt: wResults.publishedAt,
title: wResults.title,
content: wResults.content,
),
),
);
},
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 2,
horizontal: 10,
),
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Image.network(
wResults.urlToImage,
width: double.infinity,
height: 150,
fit: BoxFit.fill,
color: Colors.grey.withOpacity(1),
colorBlendMode: BlendMode.modulate,
),
),
Padding(
padding: const EdgeInsets.all(10),
child: Center(
child: Text(
wResults.title.toString().trim(),
style: Theme.of(context).textTheme.bodyText1!.merge(
const TextStyle(color: Colors.white),
),
),
),
),
Positioned(
right: 5.0,
bottom: 10.0,
child: Padding(
padding: const EdgeInsets.all(10),
child: IconButton(
onPressed: () {
setState(() {
if (DisplayFavorites.isFavoriteScreenActive) {
_isNewsScreenFavorite[index] =
!_isNewsScreenFavorite.elementAt(index);
DisplayFavorites.favoriteDataList
.remove(wResults);
} else {
_isNewsScreenFavorite[index] =
!_isNewsScreenFavorite.elementAt(index);
_isNewsScreenFavorite[index]
? DisplayFavorites.favoriteDataList
.add(wResults)
: DisplayFavorites.favoriteDataList
.remove(wResults);
}
//print(wResults.publishedAt);
});
},
icon: Icon(
DisplayFavorites.isFavoriteScreenActive
? Icons.favorite
: _isNewsScreenFavorite.elementAt(index)
? Icons.favorite
: Icons.favorite_border_outlined,
color: Colors.red,
size: 50,
),
),
),
),
],
),
),
),
);
},
);
}
}
Solution 1:[1]
You can use state management such as BLoc, ChangeNotifier, ValueNotifier, ...
Here, we should use ValueNotifier because we just need to manage only 1 value.
Firstly, we need to create a ValueNotifer:
ValueNotifier<bool> isFavoriteListenable = ValueNotifier<bool>(false); //the initial value is false
Next, to change that value, we simply use:
isFavoriteListenable.value = true;//change the value to true
Lastly, to listen to the change made to the isFavoriteListenable, we use ValueListenableBuilder. Surround the widget that need to change when isFavorite value change, just like this:
ValueListenableBuilder(
valueListenable: isFavoriteListenable,
builder: (BuildContext context, bool isFavorite,Widget child){
return NewsList(
results: favDataList,
isFavorite: isFavorite,
);
}
)
If you didn't understand or want more infomation, check this one: link
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Tr?n Trung Hi?u |
