删除项目后,StreamBuilder无法更新Flutter

时间:2020-06-01 22:06:51

标签: sqlite flutter stream-builder

我是Flutter的新手,这是我第一次问有关Stackoverflow的问题。对于任何误解,我深表歉意。我会尽力澄清。

我正在使用sqflite来存储用户的收藏夹,并在名为“收藏夹”屏幕的页面上填充数据库中的列表。 “收藏夹”页面是我底部导航栏中的项目之一。

我的问题是,当我从“收藏夹”列表中点击某个项目时,它将带我到一个屏幕,在该屏幕上我无法收藏该项目。我通过记录行数再次检查了它是否确实已从数据库中删除。但是,当我返回“收藏夹”页面时,该项目仍在列表中。如果我从底部导航栏转到页面之一,然后返回到“收藏夹”屏幕,则该项目不存在。我知道这次将再次重建页面,但我的意图是Stream会不断聆听更改。

我还实现了一张幻灯片,以关闭收藏夹屏幕上的功能,该功能可以按预期工作。但是我在两者上都使用了相同的逻辑。

“收藏夹”屏幕中的StreamBuilder代码

 StreamBuilder<List<WeekMezmurList>>(
     stream: favBloc.favStream,
      builder: (context, AsyncSnapshot<List<WeekMezmurList>> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(
            child: Text(
              "Loading Favorites...",
              style: TextStyle(fontSize: 20),
            ),
          );
        } else if (snapshot.data == null) {
          return Center(
            child: Text(
              "No Favorites yet!",
              style: TextStyle(
                fontSize: 20,
                fontWeight: FontWeight.bold,
              ),
            ),
          );
        } else {
          return ListView.builder(
            physics: BouncingScrollPhysics(),
            padding: const EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 10.0),
            itemCount: snapshot.data.length,
            itemBuilder: (BuildContext context, int index) {
              return new GestureDetector(
                onTap: () =>
                    Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (context) =>
                            AudioPlayerScreen(
                              mezmurName: snapshot.data[index].mezmurName,
                            ),
                      ),
                    ),
                child: Slidable(
                  key: new Key(snapshot.data[index].mezmurName),
                  actionPane: SlidableDrawerActionPane(),
                  actionExtentRatio: 0.25,
                  // closes other active slidable if there is any
                  controller: slidableController,
                  secondaryActions: <Widget>[
                    IconSlideAction(
                      caption: 'Share',
                      color: Colors.indigo,
                      icon: Icons.share,
                      onTap: () =>
                          _share(snapshot
                              .data[index]),
                    ),
                    IconSlideAction(
                      caption: 'Delete',
                      color: Colors.red,
                      icon: Icons.delete,
                      onTap: () =>
                          _swipeDelete(
                              context, snapshot.data[index].mezmurName),
                    ),
                  ],
                  child: Card(
                    color: Colors.white,
                    child: Padding(
                      padding: EdgeInsets.symmetric(                  
                        vertical: 15.0,
                        horizontal: 10.0,
                      ),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: <Widget>[
                          Row(
                            children: <Widget>[
                              _misbakChapter(
                                  snapshot.data[index].misbakChapters),
                              SizedBox(width: 15),
                              _displayFavoritesMisbakLines(
                                  snapshot.data[index], index),
                            ],
                          )
                        ],
                      ),
                    ),
                  ),
                ),
              );
            },
          );
        }
      },
    );

滑动以删除“收藏夹”屏幕中的代码

  // deletes the specific favorite from the sqflite db
  Future<void> _swipeDelete(BuildContext context, String mezmurName) async {
    try {
      favBloc.delete(mezmurName);
    } catch (e) {
      CupertinoAlertDialog(
        content: Text("Something went wrong. Please try again."),
        actions: <Widget>[
          CupertinoDialogAction(
            child: Text(
              "Ok",
            ),
            onPressed: () => Navigator.of(context).pop(),
          ),
        ],
      );
    }
  }

在第二个屏幕中,我具有相同的逻辑,这是我从收藏夹列表中选择一项时得到的屏幕。

favBloc.delete(widget.mezmurName);

BLoC代码,我从Medium article

中获得了概念
class FavoritesBloc{
  FavoritesBloc(){
    getFavorites();
  }

  final databaseHelper = DatabaseHelper.instance;
  // broadcast makes it to start listening to events
  final _controller = StreamController<List<WeekMezmurList>>.broadcast();
  get favStream => _controller.stream;

  void dispose() {
    _controller.close();
  }

  getFavorites () async{
    _controller.sink.add(await databaseHelper.getFavorites());
  }

  insert(WeekMezmurList fav){
    databaseHelper.insertToDb(fav);
    getFavorites();
  }

  delete(String mezmurName){
    databaseHelper.delete(mezmurName: mezmurName);
    getFavorites();
  }
}

删除数据库类中的方法

 // deleting a value from the db
   delete({String mezmurName}) async {
    var dbClient = await getDb;
    try {
      await dbClient
          .delete(TABLE, where: '$MEZMUR_NAME = ?', whereArgs: [mezmurName]);
    } catch (e) {

    }
  }

我尝试研究此问题,但发现的所有内容仅用于远程数据库。

为了更清楚一点,我拍了screen record.

提前谢谢!

0 个答案:

没有答案