1

I have a list of items that I am grabbing from a local database like this and displaying them in a list, when an item is clicked a bottom sheet appears where the user can add or remove said item from favorites list, the feature works flawlessly except the UI part with the icon and text doesn't change state (supposed to go from border_favorite and 'add to favorites' to filled_favorite and 'remove from favorites' and vice versa) even when using setState() the icon/text stay the same they only change when I close down the bottom sheet and reopen it again.

Q: What is causing this behaviour ? and how can I possibly fix this bug?

This is the bottom sheet's code:

//isBookmarked here is a field in the DB that I get elsewhere in the database
//that variable is working just fine the console log reports show that everything is in its place
//the problem is that the icon and title of the ListTile widget are not updating as they should
void trriggerBottomsheet(context, Word wrd) {
    showModalBottomSheet(
        context: context,
        builder: (BuildContext buildCtx) {
            return Container(
                child: Wrap(
                    children: <Widget>[ 
                        ListTile(
                            onTap: () {
                                isBookmarked == true
                                  ? databaseHelper.removeFromFavorite(wrd.wordId)
                                  : databaseHelper.addToFavorite(wrd.wordId);
                                setState(() {isBookmarked = !isBookmarked;});
                            },
                            leading: isBookmarked == true
                              ? Icon(Icons.favorite, color: Colors.red[300],)
                              : Icon(Icons.favorite_border),
                            title: isBookmarked == true
                              ? Text('remove from favorites')
                              : Text('add to favorites'),
                        ), 
                    ],
                ),
            );
        }
    );
}
Thorvald
  • 3,424
  • 6
  • 40
  • 66

1 Answers1

1

You can use StateSetter with StatefulBuilder when show bottomsheet.

void trriggerBottomsheet(context, Word wrd){
    showModalBottomSheet(){
       context: context,
       builder: (context){
          return StatefulBuilder(
             builder: (BuildContext ctx, StateSetter stateSetter){
                return Container(
                    child: Wrap(
                        children: <Widget>[ 
                            ListTile(
                                onTap: () {
                                    isBookmarked == true
                                      ? databaseHelper.removeFromFavorite(wrd.wordId)
                                      : databaseHelper.addToFavorite(wrd.wordId);
                                    stateSetter(() {
                                      isBookmarked = !isBookmarked;
                                    })
                                    setState(() {
                                      setState(() {
                                        isBookmarked = !isBookmarked;
                                      });
                                      isBookmarked = !isBookmarked;
                                    });
                                },
                                leading: isBookmarked == true
                                  ? Icon(Icons.favorite, color: Colors.red[300],)
                                  : Icon(Icons.favorite_border),
                                title: isBookmarked == true
                                  ? Text('remove from favorites')
                                  : Text('add to favorites'),
                            ), 
                        ],
                    ),
                );
             }
          );
       }
    }
}
Thorvald
  • 3,424
  • 6
  • 40
  • 66
blokberg
  • 849
  • 8
  • 11
  • that worked but it still has some bugs like when I click the tile it changes the UI as it is supposed to be when I close the sheet and open it again it displays the previous state not the recent change when I close it again and reopen it the second time only then it displays the recent update (I hope I'm making sense here!) – Thorvald Dec 10 '20 at 09:37
  • If the variable is accessible for the whole class, the edited answer will work. i hope i understood correctly your problem. – blokberg Dec 10 '20 at 10:43
  • this is the most bizarre thing that ever happened to me, you edited code still didn't work so I decided to keep tweaking it in hopes to achieve what I am looking for, I just submitted an edited to your answer that looks odd but surprisingly it worked (everything was a total coincidence it was literally a typo but who knew it would work!) – Thorvald Dec 10 '20 at 10:52
  • Although it works, I don't think this is a correct way. There are too many "setState" and this is not good for your application performance and principle of clean code. Maybe, you should research a little more. Or if you share your complete code, a more correct way can be found. – blokberg Dec 10 '20 at 11:13
  • yes, this is no where close to clean code, I'll be doing more research into it – Thorvald Dec 10 '20 at 11:22