sqlite 删除项目后StreamBuilder未更新Flutter

vjhs03f7  于 2023-02-23  发布在  SQLite
关注(0)|答案(1)|浏览(174)

我是Flutter的新手,这是我第一次在Stackoverflow上提问。我为任何误解道歉。我会尽我所能澄清。
我正在使用sqflite来存储用户的收藏夹,并在一个名为"收藏夹"屏幕的页面上填充数据库中的列表。这个"收藏夹"页面是底部导航栏中的一个项目。
我的问题是,当我点击收藏夹列表中的一个项目时,它会将我带到一个屏幕,在那里我可以取消收藏该项目。我通过记录行数来仔细检查它是否真的从数据库中删除。但当我返回收藏夹页面时,该项目仍然在列表中。如果我从底部导航栏转到其中一个页面,然后返回收藏夹屏幕,项目不存在。我知道这个页面正在重建,但我的意图是流将不断监听更改。
我还在fav屏幕上实现了一个slide to dismiss功能,它可以按预期工作。但是我在两者上使用了相同的逻辑。

    • 收藏夹屏幕中的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(),
          ),
        ],
      );
    }
  }

我在第二个屏幕中也有同样的逻辑,当我点击Fav列表中的一个项目时得到的屏幕。

favBloc.delete(widget.mezmurName);
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();
  }
}
    • 删除DB类中的方法**
// 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.
先谢谢你!

vwkv1x7d

vwkv1x7d1#

第一个屏幕上的StreamBuilder不随所做的更改而更新的原因是它使用了FavoritesBloc()的另一个示例。如果您希望使用单个示例全局访问块,可以将其声明为

final favBloc = FavoritesBloc();

否则,您可以按照注解中的建议,在屏幕之间传递FavoritesBloc作为参数。

相关问题