Reputation: 48
Questions:
1-) I have a data lists coming from sqlite database and I want to show them in UI. Also when user dismiss a card I want to delete it from database but if user taps undo then I want to bring it back. The problem is when I dismiss a card it's giving error:
A dismissed Dismissible widget is still part of the tree.
I searched solution for this problem but none of them fit my case because I use Bloc for these operations and other solutions were about setState
You can see in here: GIF
2-) Also when I swipe card card's background color clipping: Photo
How to fix these issues?
return Dismissible(
key: Key(widget.task.id.toString()),
background: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.red,
),
),
onDismissed: (direction) async {
Task copied = widget.task;
taskBloc.deleteTask(widget.task.id);
changeValue(widget.task.categoryId, false);
Flushbar(
messageText: Text('Task deleted', style: bodyText.copyWith(
color: Colors.white
)),
duration: Duration(seconds: 10),
margin: EdgeInsets.all(8),
borderRadius: 8,
icon: Icon(FontAwesomeIcons.infoCircle, color: widget.color),
flushbarStyle: FlushbarStyle.FLOATING,
dismissDirection: FlushbarDismissDirection.HORIZONTAL,
mainButton: FlatButton(
onPressed: () async {
taskBloc.addTask(copied);
changeValue(widget.task.categoryId, true);
},
child: Text('Undo', style: bodyText.copyWith(color: widget.color)),
),
)..show(context);
}),
Upvotes: 2
Views: 3329
Reputation: 81
You just forget to remove element to current list and refresh with setState(() {})
return Dismissible(
key: Key(widget.task.id.toString()),
background: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.red,
),
),
onDismissed: (direction) async {
Task copied = widget.task;
taskBloc.deleteTask(widget.task.id);
changeValue(widget.task.categoryId, false);
setState(() {})
Flushbar(
messageText: Text('Task deleted', style: bodyText.copyWith(
color: Colors.white
)),
duration: Duration(seconds: 10),
margin: EdgeInsets.all(8),
borderRadius: 8,
icon: Icon(FontAwesomeIcons.infoCircle, color: widget.color),
flushbarStyle: FlushbarStyle.FLOATING,
dismissDirection: FlushbarDismissDirection.HORIZONTAL,
mainButton: FlatButton(
onPressed: () async {
// to success rollback you must change id because of (Key(widget.task.id.toString())),
// otherwise you will get the same error
taskBloc.addTask(copied);
changeValue(widget.task.categoryId, true);
},
child: Text('Undo', style: bodyText.copyWith(color: widget.color)),
),
)..show(context);
}),
Upvotes: 0
Reputation: 3159
void _onDismissed(BuildContext context, index) => setState(
() {
FavouriteSong favouriteSong = favouriteSongs[index];
favouriteSongs.removeAt(index);
BlocProvider.of<FavouriteSongBloc>(context)
.add(DeleteFavouriteSong(favouriteSong: favouriteSong));
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content:
AutoSizeText("${favouriteSong.title} ကိုဖျက်လိုက်ပါပြီ။"),
duration: const Duration(seconds: 3),
action: SnackBarAction(
label: 'မဖျက်တော့ပါ',
onPressed: () {
favouriteSongs.insert(index, favouriteSong);
BlocProvider.of<FavouriteSongBloc>(context).add(
CreateFavouriteSong(favouriteSong: favouriteSong),
);
},
),
),
);
},
);
Upvotes: 0
Reputation: 1180
You can achieve this passing confirmDismiss in the Dismissible widget as given below which should return either true else false;
confirmDismiss: (val) async {
return await AlertDialog(
title: Text('Delete'),
content: Text('Are you sure to delete?'),
actions:[
FlatButton(
child:Text("Yes"),
onPressed:()=>Navigator.pop(context,true)
),
FlatButton(
child:Text("No"),
onPressed:()=>Navigator.pop(context,false)
),
],
)??false;
}
After that the onDismissed is called only when the Yes button is clicked . after the dismissed is called remove the item from the current list
Upvotes: 7