Flutter смахивание виджета с экрана
Доброго времени суток.
Подскажите пожалуйста, как сделать, чтобы виджет следовал за движением свайпа, а когда свайп завершиться, то я мог выполнить setState, чтобы скрыть виджет из дерева?
Я пытался сделать следующим образом, через GestureDetector по событию onVerticalDragEnd менял состояние и виджет скрывался, но мне нужно, чтобы виджет, пока пользователь продолжает движение пальца следовал за ним, то есть, добавить отзывчивость эдакую.
Попробовал сделать через событие onVerticalDragUpdate, достаю из него delta смещение и к элементу positioned добавляю это смещение в top параметр. Теперь работает следование за пальцем, но не работает событие onVerticalDragEnd.
Пытался использовать Draggable, но, как я понял, он тоже в этой ситуации не работает. Подскажите, пожалуйста, как реализовать такое окошко?
Код этого кусочка:
// Модальное окно (панелька) выбора
if (_isChoiceModalOpen)
Positioned(
top: _modalTopOffset,
child: GestureDetector(
child: AppDrawerChoiceModalView(),
onVerticalDragEnd: (_) => setState(() {
_isChoiceModalOpen = false;
}),
onVerticalDragUpdate: (DragUpdateDetails details) => setState((){
_modalTopOffset += details.delta.dy;
}),
),
),
Оно лежит внутри Stack'а, поэтому Positioned работает.
Полный код с родительским виджетом:
class _AppDrawerViewState extends State<AppDrawerView> {
late bool _isChoiceModalOpen;
late double _modalTopOffset;
@override
void initState() {
_isChoiceModalOpen = false;
_modalTopOffset = 0.0;
super.initState();
}
@override
Widget build(BuildContext context) {
final EdgeInsets notchInset = MediaQuery.of(context).padding;
final Size size = MediaQuery.of(context).size;
return Drawer(
child: Stack(
children: <Widget>[
Container(
color: AppColors.secondaryBackground,
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
GestureDetector(
child: Image.asset("assets/screens/main/images/avatar.png"),
onTap: () => setState(() {
_isChoiceModalOpen = true;
}),
),
Divider(
height: 3,
color: Colors.black,
),
// Главная
AppDrawerTileView(
icon: Icons.home_outlined,
),
// Новости
AppDrawerTileView(
icon: Icons.article_outlined,
),
// Выход
AppDrawerTileView(
icon: Icons.logout_outlined,
),
],
),
),
// Модальное окно (панелька) выбора
if (_isChoiceModalOpen)
Positioned(
top: _modalTopOffset,
child: GestureDetector(
child: AppDrawerChoiceModalView(),
onVerticalDragEnd: (_) => setState(() {
_isChoiceModalOpen = false;
}),
onVerticalDragUpdate: (DragUpdateDetails details) => setState((){
_modalTopOffset += details.delta.dy;
}),
),
),
]
),
);
}
}
Лишние элементы, виджеты и т.п. убрал, чтобы была понятна суть и не было совсем неразборчиво большого кода.
Здесь происходит следующее. При инициализации менюшки, модальное окно закрыто и отступ равен нулю. По нажатию на аватарке в шапке меню открывается модальное окошко.
GestureDetector(
child: Image.asset("assets/screens/main/images/avatar.png"),
onTap: () => setState(() {
_isChoiceModalOpen = true;
}),
),
Нужно сделать возможность его смахивать.
Ответы (1 шт):
Нашёлся виджет для решения этой проблемы. Dismissible с параметром direction: DismissDirection.down