#flutter
#flutter
Вопрос:
Вопросы:
1-) У меня есть списки данных, поступающие из базы данных sqlite, и я хочу показать их в пользовательском интерфейсе. Также, когда пользователь закрывает карточку, я хочу удалить ее из базы данных, но если пользователь нажимает отменить, я хочу вернуть ее обратно. Проблема в том, что когда я удаляю карту, она выдает ошибку:
Отклоненный удаляемый виджет по-прежнему является частью дерева.
Я искал решение этой проблемы, но ни одно из них не подходит для моего случая, потому что я использую 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);
}),
Ответ №1:
Вы можете добиться этого, передав 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 вызывается только при нажатии кнопки Yes . после вызова dismissed элемент удаляется из текущего списка
Комментарии:
1. спасибо за ответ @Khadga, но я не хочу показывать диалоговое окно, я просто хочу показать панель управления (своего рода панель закусок), и если пользователь нажимает кнопку отмены, я должен вернуть ее, иначе она должна быть удалена
2. Кроме того, поскольку я использую StreamBuilder для удаления, я думаю, что нет необходимости удалять элемент из списка, потому что StreamBuilder уже обновляется, когда что-либо меняется (например, удаление элемента или добавление элемента)
3. @WildHunter Как вы этого добились. Можете ли вы поделиться с нами? Я также сталкиваюсь с такой же проблемой. Я использую SnackBar и повторно вставляю, когда пользователь нажимает кнопку отмены.
Ответ №2:
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),
);
},
),
),
);
},
);
Ответ №3:
Вы просто забываете удалить элемент в текущий список и обновить с помощью 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);
}),