Search code examples
flutterdartlistviewfuturebuilder

Update item widget from local database list


I'm using a ready-made local database in my application and the problem is that I can't update one item from the list. If I add a chapter to favorites, then the button's state is updated only after the page is reopened. Likewise, the favorites list is updated only when the page is reopened. Right now when I add/remove favorites, I dynamically load the entire list so that it updates the values, but I only need to update one item, how can I do this using a provider? I didn’t give code examples, because I want to understand exactly the logic of actions

UPD:

My code:

@override
  Widget build(BuildContext context) {
    return FutureBuilder<List>(
      future: _databaseQuery.getAllChapters(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
      return snapshot.connectionState == ConnectionState.done &&
            snapshot.hasData
        ? CupertinoScrollbar(
            child: ListView.builder(
              physics: const BouncingScrollPhysics(),
              itemCount: snapshot.data!.length,
              itemBuilder: (BuildContext context, int index) {
                return MainChapterItem(
                  item: snapshot.data![index],
                );
              },
            ),
          )
        : const Center(
            child: CircularProgressIndicator.adaptive(),
          );
  },
);

}

Item:

final MainChapterItemModel item;

@override
Widget build(BuildContext context) {
return Material(
  child: InkWell(
    child: Container(
      padding: const EdgeInsets.all(8),
      child: Row(
        children: [
          IconButton(
            icon: item.favoriteState == 0
                ? const Icon(CupertinoIcons.bookmark)
                : const Icon(CupertinoIcons.bookmark_fill),
            splashRadius: 22,
            splashColor: const Color(0xff81b9b0),
            onPressed: () {
              context.read<BookmarkButtonState>().addRemoveChapterBookmark(
                  item.favoriteState == 0 ? 1 : 0, item.id);
            },
          ),
          const SizedBox(
            width: 8,
          ),
          Flexible(
            child: ListTile(
              contentPadding: EdgeInsets.zero,
              title: Padding(
                padding: const EdgeInsets.only(bottom: 8),
                child: Text(
                  item.chapterNumber,
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
              subtitle: Html(
                data: item.chapterTitle,
                style: {
                  '#': Style(
                    fontSize: const FontSize(17),
                    padding: EdgeInsets.zero,
                    margin: EdgeInsets.zero,
                  ),
                  'small': Style(
                    fontSize: const FontSize(8),
                  ),
                  'a': Style(
                    fontSize: const FontSize(14),
                    color: Colors.blue,
                  ),
                },
              ),
            ),
          ),
        ],
      ),
    ),
    onTap: () {},
  ),
);
}

The problem is that when I add to favorites or delete, the button state is not updated. And in the favorites list, the item is not deleted on click, but it disappears after the page is reopened:

IconButton(
        icon: item.favoriteState == 0
            ? const Icon(CupertinoIcons.bookmark)
            : const Icon(CupertinoIcons.bookmark_fill),
        splashRadius: 22,
        splashColor: const Color(0xff81b9b0),
        onPressed: () {
          context.read<BookmarkButtonState>().addRemoveChapterBookmark(
              item.favoriteState == 0 ? 1 : 0, item.id);
        },
      ),

Provider code:

final DatabaseQuery _databaseQuery = DatabaseQuery();

DatabaseQuery get getDatabaseQuery => _databaseQuery;

addRemoveChapterBookmark(int state, int chapterId) {
_databaseQuery.addRemoveFavoriteChapter(state, chapterId);
notifyListeners();

Solution

  • I solved the problem by signing all lists to listen to databaseQuery in the provider:

    future: context.watch<BookmarkButtonState>().getDatabaseQuery.getAllChapters(),