如何在Flutter中实现对Dismissible widget的删除和撤消操作



问题:

1-(我有一个来自sqlite数据库的数据列表,我想在UI中显示它们。另外,当用户丢弃一张卡时,我想从数据库中删除它,但如果用户点击"撤消",我想把它带回来。问题是当我驳回一张卡时,它给出了错误:

一个已被驳回的Dismissible小部件仍然是树的一部分

我搜索了这个问题的解决方案,但没有一个适合我的情况,因为我使用Bloc进行这些操作,而其他解决方案都是关于setState 的

你可以在这里看到:GIF

2-(此外,当我刷卡的背景色剪辑:照片

如何解决这些问题?

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);
}),

您可以在Dismissible小部件中实现此传递confirmDismiss,如下所示,它应该返回true或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;    
}

之后,只有在单击"是"按钮时才会调用onDismissed。在调用被驳回后,从当前列表中删除该项目

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),
);
},
),
),
);
},
);

您只是忘记了将元素删除到当前列表中,并使用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);
}),

最新更新