Don Boots
Don Boots

Reputation: 2166

Dismissing a Dismissible with Flutter/Dart

In the majority of the Dismissible examples provided by Flutter, they are dismissing items within a ListView. For example, this.

What I am currently doing is this:

Widget build(BuildContext context) {
  return new Scaffold(
    key: _scaffoldKey,
    appBar: new AppBar(
      title: new Text(widget.title),
    ),
    body: new Center(
      child: new ListView(
        children: <Widget>[
          new Dismissible(
            key: personKey,
            child: new Text('Dismiss Me'),
            onDismissed: (DismissDirection direction) {}
          )
        ],
      ) // end ListView
    ) // end Center
  ); // end return
} // end build()

After I dismiss the text box, I get the error:

A dismissed Dismissible widget is still part of the tree.

Make sure to implement the onDismissed handler and to immediately remove the Dismissible widget from the application once that handler has fired.

Digging through the Dismissible source at , I see that it checks that status of _resizeAnimation, but I'm not sure how that fits into the grand scheme of a Dismissible constructor or onDismissed handler.

Upvotes: 56

Views: 39294

Answers (7)

A dismissed Dismissible widget is still part of the tree. Make sure to implement the onDismissed handler and to immediately remove the Dismissible widget from the application once that handler has fired. See also: https://flutter.dev/docs/testing/errors

Upvotes: 0

Manuel Mayrhofer
Manuel Mayrhofer

Reputation: 1

Be careful if you use some kind of ListView you have to put the UniqueKey in that list, the dismissible also has another key.

body: ReorderableListView.builder(
  key: UniqueKey(),  //important when deleting Dismissible
  itemCount: db.toDoList.length,
  itemBuilder: (BuildContext context, int index) {
    return Dismissible(
      key: **Key**('$index'
    ),
  }
  ...

Upvotes: 0

Salil Luley
Salil Luley

Reputation: 1421

Please try this.I provided UniqueKey as key to Dismissible widget, and it worked just fine.

key: UniqueKey(), 

Upvotes: 127

Mike O.
Mike O.

Reputation: 1045

Make sure the values you're passing to the key parameters are unique as well. And DO NOT use the index of an item. Since after removing an item from an array, the array will shift the positions of the items, the Dismissable widget will not recognize the removal of an item.

Upvotes: 22

sanjay singh Bisht
sanjay singh Bisht

Reputation: 171

simplest way 1-> set unique id for each item of list with

var uuid = new Uuid();

  new MyItem(title: "Sanjay Singh Bisht",color:"#123ab",uniqueId:uuid.v1()));

as mentioned in above post Dismissible widget required unique id

2-> now to delete item its simple

if (items.contains(deletedItem)) {
    setState(() {
      items.remove(deletedItem);
    });
  }

3- to undo delete item just update that item id so that Dismissible widget has unique id always

setState(() {
deletedItem.uniqueId=uuid.v1();
});

Upvotes: 10

Anirudha Agashe
Anirudha Agashe

Reputation: 3530

The error comes when the widget is dismissed but not removed from the tree since the state still contains the dismissed object. Ideal implementation for onDismissed should remove the item and set the new state

So in your example you would do something like this

onDismissed: (DismissDirection direction) { dismissPerson(person); }

and in dismissPerson function remove the person and set new state.

dismissPerson(person) {
    if (_personList.contains(person)) {
    //_personList is list of person shown in ListView
      setState(() {
        _personList.remove(person);
      });
    }
}

If you refer to the same link posted in the question it now contains proper implementation for dismissible. Adding the relevant snippet of code from the link for convenience

final Widget card = new Dismissible(
      key: new ObjectKey(cardModel),
      direction: _dismissDirection,
      onDismissed: (DismissDirection direction) { dismissCard(cardModel); },

      ....

    );


void dismissCard(CardModel card) {
    if (_cardModels.contains(card)) {
      setState(() {
        _cardModels.remove(card);
      });
    }
}

Upvotes: 14

R&#233;mi Rousselet
R&#233;mi Rousselet

Reputation: 276891

The error message is pretty clear.

Make sure to implement the onDismissed handler and to immediately remove the Dismissible widget from the application once that handler has fired.

An empty function is not enough. Once an item has been dismissed, that widget has to be removed from the widget tree. Which means that you must remove the Dismissible from your ListView.

Upvotes: 0

Related Questions