I am using a list of Dismissible items and want a swipe in one direction to delete the item but a swipe in the other direction to initiate an edit of the item. However, Flutter insists that a Dismissible item must be removed from the tree in the onDismissed callback. I've tried re-inserting the item but that doesn't work. Any ideas? Extract from the code creating the list items is below:
return new Dismissible(
key: new ObjectKey(item),
direction: DismissDirection.horizontal,
onDismissed: (DismissDirection direction) {
setState(() {
item.deleteTsk();
});
if (direction == DismissDirection.endToStart){
//user swiped left to delete item
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text('You deleted: ${item.title}'),
action: new SnackBarAction(
label: 'UNDO',
onPressed: () { handleUndo(item); }
)
));
}
if (direction == DismissDirection.startToEnd){
//user swiped right to edit so undo the delete required by flutter
Async.scheduleMicrotask((){handleUndo(item);});
Navigator.of(context).pushNamed('/tskedit');
}
},
...
You can use confirmDismiss
function of Dismissible
widget for this purpose.
If you don't want the widget to get dismissed, then you just need to return false
from confirmDismiss
.
Don't use onDismissed
to do your post-swipe processing, use confirmDismiss
instead, it will provide you with the swipe direction just as onDismissed
.
Here is the official documentation for confirmDismiss
function:
Gives the app an opportunity to confirm or veto a pending dismissal. If the returned Future completes true, then this widget will be dismissed, otherwise it will be moved back to its original location. If the returned Future completes to false or null the [onResize]
and here is an example:
Dismissible(
confirmDismiss: (direction) async {
if (direction == DismissDirection.startToEnd) {
/// edit item
return false;
} else if (direction == DismissDirection.endToStart) {
/// delete
return true;
}
},
key: Key(item.key),
child: Text(item.name),
)
The Dismissible
will think your item was dismissed as long as the item key changes. Let's say your item class is MyItem
. If you implement a constructor MyItem.from
in your MyItem
class that copies the fields over, e.g.:
class MyItem {
MyItem({ @required this.title, @required this.color });
MyItem.from(MyItem other) : title = other.title, color = other.color;
final String title;
final Color color;
}
Then you can replace handleUndo(item)
with handleUndo(new MyItem.from(item))
so that your new ObjectKey(item)
will be unique from the old ObjectKey
that you used before (assuming you didn't implement operator ==
on MyItem
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With