如何解决“已关闭的可关闭小部件仍然是树的一部分”。颤振中的错误

Sam*_*der 9 flutter

我正在构建一个带有可关闭小部件、firebase 和 StreamBuilder 的 flutter 应用程序,并收到以下错误“已关闭的可关闭小部件仍然是树的一部分”。

请找到以下代码。

Expanded(
                  child: StreamBuilder(
                    stream: Firestore.instance
                        .document('/users/User1/Trips/${widget.tripId}')
                        .collection('TropDocs')
                        .snapshots(),
                    builder: (context, snapshot) {
                      if (!snapshot.hasData) return const Text("Loading....");
                      return ListView.builder(
                        itemExtent: 150.0,
                        itemCount: snapshot.data.documents.length,
                        itemBuilder: (context, index) {

final item = snapshot.data.documents[index];
                          final itemID =
                              snapshot.data.documents[index].documentID;
                          final list = snapshot.data.documents;      
return Dismissible(
   key: Key(itemID),
              // We also need to provide a function that tells our app
              // what to do after an item has been swiped away.
              onDismissed: (direction) {
                // Remove the item from our data source.

                //fBtDoc.deleteTraveldoc(item);
                //Firestore.instance.collection('/users/User1/Trips/${widget.tripId}/TropDocs/').document('$itemID').delete();
                setState(() {
                  list.removeAt(index);
                });

                // Then show a snackbar!
                Scaffold.of(context)
                    .showSnackBar(SnackBar(content: Text("$item dismissed")));
              },
              // Show a red background as the item is swiped away
              background: Container(color: Colors.red),
              child: _buildlistitem(
                            context, snapshot.data.documents[index])
);

                        }
                      );
                    },
                  ),
                )
Run Code Online (Sandbox Code Playgroud)

小智 16

在我的事业中,我使用了如下

key: Key(index),
Run Code Online (Sandbox Code Playgroud)

然后我确实将其更改如下。它正在工作

key: UniqueKey(),
Run Code Online (Sandbox Code Playgroud)


小智 14

也许,我迟到了,但我认为这对其他人有帮助。有同样的问题,甚至设置

key: Key(itemId[index]),
Run Code Online (Sandbox Code Playgroud)

没有用。然而,

key: UniqueKey(),
Run Code Online (Sandbox Code Playgroud)

非常适合我

  • 基于索引设置键的问题是,如果删除除最后一项之外的任何项目,索引仍将存在,因为行中的下一个索引将简单地占据其位置。item[0]、item[1]、item[2] -> 如果删除 item[1],列表仍将包含 item[1](item[0]、item[1]),因为 item[0]、item[1] 的增量性质索引列表。要验证这一点,只需尝试删除列表的最后一项。而其他所有项目都通过异常,而这个则没有。然而,使用项目的 ID 实际上应该可行。您可以测试一下删除最后一项是否没有错误吗? (4认同)

小智 13

原因是传递给 key 属性的值\xe2\x80\x99 不是唯一的或与列表的索引相关。\n解决方案非常简单,您所需要做的就是将 key 属性设置为 UniqueKey(),像这样:

\n
key: UniqueKey(),\n
Run Code Online (Sandbox Code Playgroud)\n


Dar*_*han 9

我认为那是因为您试图key对每个可解雇的人使用相同的内容。

key: Key(itemID)

它应该是 key: Key(itemID[index])


kas*_*hlo 5

移除 setState 块,streamBuilder 将自行重建列表

 setState(() {
   list.removeAt(index);
 });
Run Code Online (Sandbox Code Playgroud)