Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add action before Dismissible's onDismissed() action get triggered?

Tags:

flutter

I would like to add a small AlertBox before the onDismissed() action occurs?

So, the user swipe the item form the list to delete it, but just before the action occurs, I want to ask him if he is sure.

Is it possible with the current Dismissible widget?

Edit:

onDismissed: (direction) {
    final User _deletedItem = this._items[index];

    showDialog(
      context: context,
      barrierDismissible: false, // user must tap a button
      builder: (BuildContext context) {
        return AlertDialog(
          content: Text(
              'Are you sure you want to delete this?'),
          actions: <Widget>[
            FlatButton(
              child: Text('Cancel'),
              onPressed: () {
                Navigator.of(context).pop(false);
              },
            ),
            FlatButton(
              child: Text('OK'),
              onPressed: () {
                Navigator.of(context).pop(true);
              },
            ),
          ],
        );
      },
    ).then((answer) {
      if (answer == true) {
        setState(() {
          this._items.removeAt(index);
        });

        Scaffold.of(context).showSnackBar(
          SnackBar(
            content: Text("Deleted"),
            duration: Duration(milliseconds: 2000),
          ),
        );
      } else {
        setState(() {
          this._items.insert(index, _deletedItem);
        });
      }
    });
  },
like image 682
David Avatar asked Feb 04 '26 11:02

David


2 Answers

The confirmDismiss property is what you need.

like image 75
BambinoUA Avatar answered Feb 06 '26 03:02

BambinoUA


Sorry, there is no way to prevent the item from swiping using standard 'Dismissible` as of now.

If you want to achieve what you are looking for you may want to implement your custom way, by making use of GestureDetector having child ListTile and then listen for horizontalDrag() events.

The easier way I would recommend would be to let the user swipe (and let the item go away), after this immediately show a SnackBar telling user if he wants to undo that delete action, and you can handle the undo action by putting the item back again in the list.


Edit: To perform deletion and undo you can do this,

GlobalKey<ScaffoldState> _key = GlobalKey(); // added
List<String> _list = List.generate(10, (index) => "${index}");

@override
Widget build(BuildContext context) {
  return Scaffold(
    key: _key, // added
    appBar: AppBar(title: Text("App")),
    body: ListView.builder(
      itemCount: _list.length,
      itemBuilder: (context, index) {
        return Dismissible(
          key: Key(_list[index]),
          child: ListTile(title: Text(_list[index])),
          background: Container(color: Colors.red),
          onDismissed: (direction) {
            setState(() {
              // added this block 
              String deletedItem = _list.removeAt(index);
              _key.currentState..removeCurrentSnackBar()..showSnackBar(
                SnackBar(
                  content: Text("Deleted \"${deletedItem}\""),
                  action: SnackBarAction(
                    label: "UNDO",
                    onPressed: () => setState(() => _list.insert(index, deletedItem),) // this is what you needed
                  ),
                ),
              );
            });
          },
        );
      },
    ),
  );
}

Screenshot

enter image description here

like image 36
CopsOnRoad Avatar answered Feb 06 '26 04:02

CopsOnRoad