4.0 KiB
4.0 KiB
| name | description |
|---|---|
| widgets-dismissible | Flutter Dismissible - swipe-to-dismiss widgets with callbacks |
Dismissible
Dismissible allows widgets to be dismissed by swiping.
Basic Usage
Dismissible(
key: Key(item.id),
onDismissed: (direction) {
// Handle dismissal
setState(() {
items.remove(item);
});
},
child: ListTile(title: Text(item.name)),
)
Dismiss Directions
Dismissible(
key: Key(item.id),
direction: DismissDirection.horizontal, // horizontal, vertical, endToStart, startToEnd, up, down, all
onDismissed: (direction) {
if (direction == DismissDirection.endToStart) {
// Swiped left
} else {
// Swiped right
}
},
child: ListTile(title: Text(item.name)),
)
Background
Show background when dismissing.
Dismissible(
key: Key(item.id),
background: Container(
color: Colors.red,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 20),
child: Icon(Icons.delete, color: Colors.white),
),
secondaryBackground: Container(
color: Colors.green,
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20),
child: Icon(Icons.archive, color: Colors.white),
),
onDismissed: (direction) {
if (direction == DismissDirection.endToStart) {
// Delete
} else {
// Archive
}
},
child: ListTile(title: Text(item.name)),
)
Confirm Dismissal
Dismissible(
key: Key(item.id),
confirmDismiss: (direction) async {
// Show confirmation dialog
return await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: Text('Confirm'),
content: Text('Delete this item?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: Text('Cancel'),
),
ElevatedButton(
onPressed: () => Navigator.pop(context, true),
child: Text('Delete'),
),
],
),
) ?? false;
},
onDismissed: (direction) {
// Handle dismissal
},
child: ListTile(title: Text(item.name)),
)
Complete Example
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Dismissible(
key: Key(item.id),
direction: DismissDirection.endToStart,
background: Container(
color: Colors.red,
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20),
child: Icon(Icons.delete, color: Colors.white),
),
confirmDismiss: (direction) async {
return await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: Text('Delete?'),
content: Text('Are you sure?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: Text('Cancel'),
),
ElevatedButton(
onPressed: () => Navigator.pop(context, true),
child: Text('Delete'),
),
],
),
) ?? false;
},
onDismissed: (direction) {
setState(() {
items.removeAt(index);
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Item deleted')),
);
},
child: ListTile(title: Text(item.name)),
);
},
)
Key Points
- Use
Dismissiblefor swipe-to-dismiss - Provide unique
keyfor each item - Use
backgroundandsecondaryBackgroundfor visual feedback - Use
confirmDismissto confirm before dismissing - Handle
onDismissedto update state - Set
directionto control swipe directions - Works well in ListView.builder
- Update list after dismissal