0

I'm rendering a list fetched from api on the screen. I have a save button for each Item in the list which changes on click. it works fine but when I scroll the list it reverts. I think its because the list builder is building the list again and again but I can't think of a solution to fix icon state on user click. here is the part of code:

....
class NewsListBuilderItemsState extends State<NewsListBuilderItems> {
  final _repository = Repository();
  bool selected = false;
...

and here is the button:

                  GestureDetector(
                    child: Icon(selected
                        ? Icons.bookmark
                        : Icons.bookmark_border_outlined),
                    onTap: () {
                      setState(() {
                        selected = !selected;
                        _repository.addToDb(
                            widget.snapshot.data[widget.index]);

                        bloc.addToSavedNews(
                            widget.snapshot, widget.index);
                      });
                    },
                  )

enter image description here

Benyamin
  • 1,008
  • 11
  • 18

2 Answers2

0

The problem is, that you handle the "selected" state only on item level. Therefore if the item gets out of visible area, it destroys itself and if you scroll back, it recreates itself with initial state. You need to pass the selected information from above the item. Most likely at the place, where you map all the news. You should get the selected value from db (bloc) there and pass it as parameter to the news item.

Dharman
  • 30,962
  • 25
  • 85
  • 135
MartinM
  • 401
  • 4
  • 9
  • my button is here on this widget and the icon changes here so here the selected will be changed. how can I do something like that? – Benyamin Aug 16 '21 at 20:17
0

You have multiple list items, it is so obvious that you can't manage the state with just one variable. You need to make a list of boolean values, the length of the list should be equal to the length of the list. Then in setState you should change the boolean value at the index of that item.

....
   class NewsListBuilderItemsState extends State<NewsListBuilderItems> {
   final _repository = Repository();
   List<bool> selected = [];
...

Note :-

GestureDetector(
                child: Icon(selected[index]

                    ? Icons.bookmark
                    : Icons.bookmark_border_outlined),
                onTap: () {
                  setState(() {
                    selected[index] = !selected[index];
                    _repository.addToDb(
                        widget.snapshot.data[widget.index]);

                    bloc.addToSavedNews(
                        widget.snapshot, widget.index);
                  });
                },
              )
Pratham Sarankar
  • 555
  • 6
  • 10
  • I think NewsListBuilderItems is a stateful widget for every item. In widget tree, the widget above this, I mean the widget where you have the listview. You need to change the state of that widget and make every list item as stateless. – Pratham Sarankar Aug 17 '21 at 01:04