Flutter Slidable Widget Example
This article explains you how to use flutter slidable widget in flutter applications to provide options to user on swipe listview. You can also check out flutter listview related articles.
Flutter slidable widget is used to display options to users if they swipe left or right list view row. In this flutter example, we will display archive and share options on left swipe of listview row. More and delete options are displayed on right swipe of listview row.
This flutter slidable plugin has many functionalities. This plugin takes left side actions as primary and right side actions as secondary. It provides four types implicit action panes like scroll, drawer, stretch and behind. This plugin also provides two built-in slide action widget.
Flutter slidable widget is used to display dismiss animation on swipe in flutter apps. We can also disable one side using this plugin. We can also create custom animations and UI using this widget. In this flutter tutorial, you will see how flutter slidable widget will work in flutter listview when user swipe from left to right or right to left.
Add required dependency in your pubspec.yaml file
Initialize Slidable Controller for Flutter Swipe Actions
@override
void initState() {
slidableController = SlidableController(
onSlideAnimationChanged: slideAnimationChanged,
onSlideIsOpenChanged: slideIsOpenChanged,
);
super.initState();
}
void slideAnimationChanged(Animation<double> slideAnimation) {}
void slideIsOpenChanged(bool isOpen) {}
Create Flutter ListView
‘SlidableScrollActionPane List’,
‘SlidableDrawerActionPane List’,
‘SlidableStrechActionPane List’,
‘SlidableBehindActionPane List’,
‘SlidableScrollActionPane Delegate’,
‘SlidableDrawerActionPane Delegate’,
‘SlidableStrechActionPane Delegate’,
‘SlidableBehindActionPane Delegate’
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(‘Flutter Slidable Demo’),
centerTitle: true,
),
body: Center(
child: OrientationBuilder(
builder: (context, orientation) => buildList(
context,
orientation == Orientation.portrait
? Axis.vertical
: Axis.horizontal),
),
),
);
}
Widget buildList(BuildContext context, Axis direction) {
return ListView.separated(
separatorBuilder: (context, index) {
return Divider(
height: 2,
);
},
scrollDirection: direction,
itemBuilder: (context, index) {
final Axis slidableDirection =
direction == Axis.horizontal ? Axis.vertical : Axis.horizontal;
if (index < 4) {
return slidableWithLists(context, index, slidableDirection);
} else {
return slidableWithDelegates(context, index, slidableDirection);
}
},
itemCount: listItems.length,
);
}
Show Different Action Panes for Flutter Slidable
switch (index % 4) {
case 0:
return SlidableScrollActionPane();
case 1:
return SlidableDrawerActionPane();
case 2:
return SlidableStrechActionPane();
case 3:
return SlidableBehindActionPane();
default:
return null;
}
}
Create UI for horizontal and vertical list view direction
import ‘package:flutter_slidable/flutter_slidable.dart’;
class MyVerticalListView extends StatelessWidget {
MyVerticalListView(this.title);
final String title;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () =>
Slidable.of(context)?.renderingMode == SlidableRenderingMode.none
? Slidable.of(context)?.open()
: Slidable.of(context)?.close(),
child: Container(
color: Colors.white,
child: ListTile(
title: Text(title, style: TextStyle(fontSize: 22),),
),
),
);
}
}
class MyHorizontalListView extends StatelessWidget {
MyHorizontalListView(this.title);
final String title;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
width: 160.0,
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Expanded(
child: Center(
child: Text(
title,
),
),
),
],
),
);
}
}
Add Flutter Slidable Widget with Lists
return Slidable(
key: Key(listItems[index]),
controller: slidableController,
direction: direction,
dismissal: SlidableDismissal(
child: SlidableDrawerDismissal(),
onDismissed: (actionType) {
showSnackBar(context,
actionType == SlideActionType.primary ? ‘Archived’ : ‘Deleted’);
setState(() {
listItems.removeAt(index);
});
},
),
actionPane: actionPane(index),
actionExtentRatio: 0.20,
child: direction == Axis.horizontal
? MyVerticalListView(listItems[index])
: MyHorizontalListView(listItems[index]),
actions: <Widget>[
IconSlideAction(
caption: ‘Archive’,
color: Colors.blue,
icon: Icons.archive,
onTap: () => showSnackBar(context, ‘Archive’),
),
IconSlideAction(
caption: ‘Share’,
color: Colors.indigo,
icon: Icons.share,
onTap: () => showSnackBar(context, ‘Share’),
),
],
secondaryActions: <Widget>[
IconSlideAction(
caption: ‘More’,
color: Colors.grey.shade200,
icon: Icons.more_horiz,
onTap: () => showSnackBar(context, ‘More’),
closeOnTap: false,
),
IconSlideAction(
caption: ‘Delete’,
color: Colors.red,
icon: Icons.delete,
onTap: () => showSnackBar(context, ‘Delete’),
),
],
);
}
void showSnackBar(BuildContext context, String text) {
Scaffold.of(context).showSnackBar(SnackBar(content: Text(text)));
}
Add Flutter Slidable Widget with Delegates
return Slidable.builder(
key: Key(listItems[index]),
controller: slidableController,
direction: direction,
dismissal: SlidableDismissal(
child: SlidableDrawerDismissal(),
closeOnCanceled: true,
onWillDismiss: (index != 3)
? null
: (actionType) {
return showDialog<bool>(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: Colors.white,
title: Text(
‘Delete’,
style: TextStyle(color: Colors.redAccent),
),
content: Text(
‘Item will be deleted’,
style: TextStyle(color: Colors.redAccent),
),
actions: <Widget>[
FlatButton(
child: Text(
‘Cancel’,
style: TextStyle(color: Colors.redAccent),
),
onPressed: () => Navigator.of(context).pop(false),
),
FlatButton(
child: Text(
‘Ok’,
style: TextStyle(color: Colors.redAccent),
),
onPressed: () => Navigator.of(context).pop(true),
),
],
);
},
);
},
onDismissed: (actionType) {
showSnackBar(context,
actionType == SlideActionType.primary ? ‘Archived’ : ‘Deleted’);
setState(() {
listItems.removeAt(index);
});
},
),
actionPane: actionPane(index),
actionExtentRatio: 0.20,
child: direction == Axis.horizontal
? MyVerticalListView(listItems[index])
: MyHorizontalListView(listItems[index]),
actionDelegate: SlideActionBuilderDelegate(
actionCount: 2,
builder: (context, index, animation, renderingMode) {
if (index == 0) {
return IconSlideAction(
caption: ‘Archive’,
color: renderingMode == SlidableRenderingMode.slide
? Colors.blue.withOpacity(animation.value)
: (renderingMode == SlidableRenderingMode.dismiss
? Colors.blue
: Colors.green),
icon: Icons.archive,
onTap: () async {
var state = Slidable.of(context);
var dismiss = await showDialog<bool>(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: Colors.white,
title: Text(
‘Delete’,
style: TextStyle(color: Colors.redAccent),
),
content: Text(
‘Item will be deleted’,
style: TextStyle(color: Colors.redAccent),
),
actions: <Widget>[
FlatButton(
child: Text(
‘Cancel’,
style: TextStyle(color: Colors.redAccent),
),
onPressed: () => Navigator.of(context).pop(false),
),
FlatButton(
child: Text(
‘Ok’,
style: TextStyle(color: Colors.redAccent),
),
onPressed: () => Navigator.of(context).pop(true),
),
],
);
},
);
if (dismiss) {
state.dismiss();
}
},
);
} else {
return IconSlideAction(
caption: ‘Share’,
color: renderingMode == SlidableRenderingMode.slide
? Colors.indigo.withOpacity(animation.value)
: Colors.indigo,
icon: Icons.share,
onTap: () => showSnackBar(context, ‘Share’),
);
}
}),
secondaryActionDelegate: SlideActionBuilderDelegate(
actionCount: 2,
builder: (context, index, animation, renderingMode) {
if (index == 0) {
return IconSlideAction(
caption: ‘More’,
color: renderingMode == SlidableRenderingMode.slide
? Colors.grey.shade200.withOpacity(animation.value)
: Colors.grey.shade200,
icon: Icons.more_horiz,
onTap: () => showSnackBar(context, ‘More’),
closeOnTap: false,
);
} else {
return IconSlideAction(
caption: ‘Delete’,
color: renderingMode == SlidableRenderingMode.slide
? Colors.red.withOpacity(animation.value)
: Colors.red,
icon: Icons.delete,
onTap: () => showSnackBar(context, ‘Delete’),
);
}
}),
);
}







Pingback: Flutter Time Planner Example - CodingWithDhrumil
Pingback: Flutter Cupertino Segmented Control Example - CodingWithDhrumil
Pingback: Slide Animation in Flutter App - CodingWithDhrumil
Pingback: Flutter Google Maps Custom Marker - CodingWithDhrumil