I am building a fluter app with dismissible widget, firebase and StreamBuilder and getting following error "A dismissed Dismissible widget is still part of the tree."
Please find the below code sniped for the same.
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])
);
}
);
},
),
)
Probably, I'm late, but I think it will be helpful for others. Had the same problem and even setting
key: Key(itemId[index]),
didn't work. However,
key: UniqueKey(),
worked perfectly for me
I think that's because you are trying to use same key
for every dismissible.
key: Key(itemID)
It should be key: Key(itemID[index])
In my cause, I have used as below
key: Key(index),
and then I did change it as below. It's working
key: UniqueKey(),
Remove setState block, streamBuilder will rebuild list by itself
setState(() {
list.removeAt(index);
});
The reason is that the value passed to the key property isn't unique or related to the index of a list. The solution is quite simple and all you need to do is set the key property to UniqueKey(), like this:
key: UniqueKey(),
I would have done something like this to remove swiping from right to left
confirmDismiss: (direction) {
return Future.value(direction == DismissDirection.endToStart);
},
onDismissed: (direction) {
setState(() {
list.removeAt(index);
});
},
A workaround for a single widget dismissible is shown below and for the dismissible in a list write logic according to the code provided. Here we put an if condition for the Dismissible and in onDismissed
just set that bool variable to false so that it will not remains in the widget tree.
if (_boolVariable)
Dismissible(
key: Key('anyString'),
onDismissed: (direction) {
//your code here
setState(() => _boolVariable = false);
},
child: YourWidget())
将密钥更改为:
key: UniqueKey(),
try to change remove(index) function under onDismissed: like that;
***- mylist.removeAt(index);***
Because, remove function removes items. And yo dismissed nothing but looks dismissed and trows error : A dismissed Dismissible widget is still part of the tree.
***- so must be declared like this : mylist.remove(item);***
I have had a similar problem, but a little bit more complex. I wanted to use ReordableListView
with ListTile
's along with Dismissible
.
Container(
child: ReorderableListView.builder(
onReorder: (int oldIndex, int newIndex) {},
itemCount: _savedLocations.length,
itemBuilder: (context, index) {
LocationModel? locationItem = _savedLocations?[index];
return Dismissible(
// key: UniqueKey(),
// key: Key('$index'),
key: Key('${locationItem?.id}'),
onDismissed: (direction) {
LocationModel dismissed = _savedLocations[index];
setState(() { _savedLocations.removeAt(index); });
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Location: $dismissedValue dismissed')));
},
child: ListTile(
// key: Key('$index'),
// key: UniqueKey(),
key: ValueKey('${locationItem?.id}'),
title: Text(locationItem?.name ?? ''),
subtitle: Text(locationItem?.country ?? ''),
),
),
),
I have started with ListTile
and added key: Key('$index')
, everything was working as expected. Then I wanted to add dismiss functionality so I wrapped it in Dismissible
. Dismissible
item also expect unique key, but I found out that actions on items with key: UniqueKey()
assigned stopped working (dragging, dismissible).
Note: I have left commented out lines with wrong keys. For example: Key('$index')
cannot be used for Dismissible
because it will be deleted at the time of dismissal and causes error. I strongly suggest you to try it and see the error when trying to dismiss list item by swiping left or right.
Solution was to set Dismissible
key to unique item Key('${locationItem?.id}')
and ListTile
key to ValueKey('${locationItem?.id}')
. In this is case both Drag&drop (reordable) and dismissible funcionality work as expected.
Reference: How to use ReorderableListView with DismissDirection in Flutter?
Why giving index as key not working
key: Key(index)
: in this case the widget in widget tree will be bind in to the key which is the index, when you remove an item from the tree the build method will re-run and it looks for the widget with the key is there and always it can find the index there as the next element in the list will be replaced by the current item with "same index" that is why you are not getting this error when you try to remove it from end of the list the index can't be replaced because there is no element after this so instead of using index as key use something unique in that element like the id of element or UniqueKey()
key: Key(index)
will throw error
key: Key(item.id),
or key: UniqueKey(),
I'am also fall this error & debug with the following logic Instead of
key: Key(itemID),
use
key: Key(itemID[itemIDIndex]),
and in your setstae logic replace
setState(() {
list.removeAt(index);
});
with
setState(() {
itemID.removeAt(itemIDIndex);
});
this will solve the problem.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.