How can I implement a ListView
that has a Dismissible
widget, and when I swipe, I can delete the item, but how can I bring it back when tapping say
If you are retrieving data from a remote server such as firestore, follow this example below:
StreamBuilder<QuerySnapshot>(
stream: db.collection("collection name").snapshots(),
// ignore: missing_return
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Center(child: Text('Sorry something went wrong'));
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
return ListView.builder(
itemCount: snapshot.data.docs.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index){
DocumentSnapshot document = snapshot.data.docs[index];
final documentID = snapshot.data.docs[index].id;
final list = snapshot.data.docs;
return Dismissible(
confirmDismiss: (direction) => promptUser(direction), //U can use showDialog to build this method for confirmation if need be.
// Each Dismissible must contain a Key. Keys allow
// Flutter to uniquely identify widgets.
key: Key(documentID),
onDismissed: (direction){
removeFromDb(documentID);
setState(() {
// Remove the item from the data source.
list.removeAt(index);
String action;
if (direction == DismissDirection.endToStart) {
removeFromDb(documentID);
action = "deleted";
}
_key.currentState
..removeCurrentSnackBar()
..showSnackBar(
SnackBar(
content: Text("Data $documentID $action"),
action: SnackBarAction(
label: "UNDO",
onPressed: () => setState(() => list.insert(index, deletedItem),)
),
),
);
});
},
// Show a red background as the item is swiped away
background: Container(
color: Colors.amber,
padding: EdgeInsets.symmetric(horizontal: 20),
alignment: AlignmentDirectional.centerEnd,
child: Icon(
Icons.delete,
color: Colors.white,
),
),
child: GestureDetector(
onTap: () => _onSelected(index),
child: Container(
//==> change bg color when index is selected ==>
color: _selectedIndex != null && _selectedIndex == index
? Colors.grey[100]
: Colors.white,
padding: EdgeInsets.only(top: 15, left: 10, right: 10),
height: 180,
width: double.maxFinite,
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.all(5.0),),
Padding(
padding: EdgeInsets.only(top: 30, left: 1),
child: Column(
children: [
Text(
document.data()['same name in document/field'],
style: TextStyle(
decorationStyle: TextDecorationStyle.double,
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.w700,
),
),
SizedBox(
height: 9,
),
Text(document.data()['same name in document/field'],
style: TextStyle(
decorationStyle: TextDecorationStyle.double,
color: Colors.black87,
fontSize: 16,
),),
SizedBox(
height: 9,
),
Text(document.data()['same name in document/field'],
style: TextStyle(
decorationStyle: TextDecorationStyle.double,
color: Colors.black87,
),
),
SizedBox(
height: 6,
),
Text(document.data()['same name in document/field'],
style: TextStyle(
decorationStyle: TextDecorationStyle.double,
color: Colors.black87,
),
),
],
),
),
SizedBox(
width: 15,
),
Container(
width: 1,
height: 130,
color: Colors.black54,
),
SizedBox(
width: 8,
),
Padding(
padding: EdgeInsets.only(top: 20, bottom: 20),
child: Container(
height: 120,
width: 145,
child: SingleChildScrollView(
child: Align(
alignment: Alignment.center,
child: Text(
document.data()['same name in document/field'],
style: TextStyle(
color: Colors.black
),
),
))),
),
],
),
),
),
),
);
}
);
})
Couldn't show screenshot but this will work alright especially if you understand Firestore
All you needed is
_list.insert(index, yourDeletedItem);
Here is the complete code with SnackBar
added.
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