'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