【问题标题】:A dismissed Dismissible widget is still part of the tree已关闭的 Dismissible 小部件仍然是树的一部分
【发布时间】:2020-12-19 07:18:44
【问题描述】:

关于这个错误似乎有很多问题,但我还没有找到适合我的情况的答案。

我看到的行为是 Dismissible 有效,它会触发并删除该项目,但有一段时间它在 ListView 中显示错误。我猜它正在等待基于 Stream 更新树,这反过来又会从 Firebase 中删除记录。

我的 StreamBuilder...

return StreamBuilder<List<Person>>(
      stream: personBloc.personsByUserId(userId),
      builder: (context, snapshot) {

...

}

我的 ListView.builder()

ListView.builder(
                      itemCount: snapshot.data.length,
                      itemBuilder: (context, index) {
                        var person = snapshot.data[index];

                        return GestureDetector(
                          onTap: () {
                            Navigator.of(context)
                                .pushNamed('/reading/${person.personId}');
                          },
                          child: Dismissible(
                            key: Key(person.personId),
                            direction: DismissDirection.endToStart,
                            onDismissed: (direction) {
                              personBloc.deletePerson(person.personId);
                            },
                            background: Container(
                              child: Padding(
                                padding: const EdgeInsets.all(15.0),
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.end,
                                  children: [
                                    Icon(
                                      FontAwesomeIcons.trash,
                                      color: Colors.white,
                                    ),
                                    Text(
                                      'Delete',
                                      style: TextStyle(color: Colors.white),
                                      textAlign: TextAlign.right,
                                    ),
                                  ],
                                ),
                              ),
                              color: Colors.red,
                            ),
                            child: AppCard(
                              //Bunch of properties get set here
                            ),
                          ),
                        );
                      },
                    

我的删除人

  deletePerson(String personId) async {
    fetchPersonId(personId).then((value) {
      if (value.imageUrl.isNotEmpty) {
        removeImage();
      }

      db.deletePerson(personId);
    });
  }

我尝试将 onDismissed 更改为 confirmDismiss,但没有成功。

有什么建议吗?

【问题讨论】:

  • 我认为问题出在流程的顺序上。您正在从列表中删除该行,但它仍然存在于原始数据中,并且在您的回调被触发之前您实际上并没有删除它。尝试从您提供给列表的数据中立即删除该项目,如果成功则等待回调,如果没有将其恢复,我希望它有所帮助
  • 我尝试在 setState() 语句中添加 snapshot.data.removeAt(index),但行为没有改变。
  • 我猜它发生在每个包裹在 Stream Builder 中的 Dismissible 小部件上,它在实际从数据库中删除之前需要一些时间,但 Stream Builder 在那之前仍然会听它。您是否尝试过使用 Future Builder?
  • 我同意@AldyYuan。看起来Stream 使用具有特定ID 的项目重建ListView,因为它尚未被删除,一旦它被删除并更新视图,它就会消失。但我觉得这很奇怪,因为如果你不更新Stream 正在收听的数据,Stream 没有理由重建ListView。

标签: flutter


【解决方案1】:

当您使用 Dismissible 小部件关闭但尚未从 ListView.builder 使用的列表中删除该项目时,会发生这种情况。如果您的列表存储在本地,延迟不是问题,您可能永远不会看到这个问题,但是因为您使用的是Firestore(我假设,基于您提到的Firebase),那么会有一些要求从DB 中删除项目与在应用程序上更新列表之间的延迟。为避免此问题,您可以将本地列表与来自Stream 的列表分开管理。随着流的变化更新状态,但允许您从本地列表中本地删除项目并避免此类查看错误。

【讨论】:

    【解决方案2】:

    我最终对我的代码进行了一些更改以解决这个问题。

    我在我的 bloc 中添加了一个 BehaviourSubject 来监控删除是否发生。在 firestore 删除开始时,我将其设置为 true,然后将 .then 添加到删除以将其设置回 false。

    然后我在屏幕上的 ListView 周围添加了一个 Streambuilder 来监控它的值并在为 true 时显示一个 CircularProgressIndicator。

    现在看起来像这样:

    感谢您的帮助。

    【讨论】:

      猜你喜欢
      • 2022-01-23
      • 1970-01-01
      • 2021-11-30
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多