У меня есть стек, в котором можно перемещать несколько виджетов. Кроме того, контейнер, в котором находится стек, имеет GestureDetector для запуска по onTapDown и onTapUp. Я хочу, чтобы эти события onTap запускались только тогда, когда пользователь нажимает за пределы виджета в стеке. Я пробовал следующий код:
class Gestures extends StatefulWidget {
@override
State<StatefulWidget> createState() => _GesturesState();
}
class _GesturesState extends State<Gestures> {
Color background;
Offset pos;
@override
void initState() {
super.initState();
pos = Offset(10.0, 10.0);
}
@override
Widget build(BuildContext context) => GestureDetector(
onTapDown: (_) => setState(() => background = Colors.green),
onTapUp: (_) => setState(() => background = Colors.grey),
onTapCancel: () => setState(() => background = Colors.grey),
child: Container(
color: background,
child: Stack(
children: <Widget>[
Positioned(
top: pos.dy,
left: pos.dx,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onPanUpdate: _onPanUpdate,
// onTapDown: (_) {}, Doesn't affect the problem
child: Container(
width: 30.0,
height: 30.0,
color: Colors.red,
),
),
)
],
),
),
);
void _onPanUpdate(DragUpdateDetails details) {
RenderBox renderBox = context.findRenderObject();
setState(() {
pos = renderBox.globalToLocal(details.globalPosition);
});
}
}
Однако, когда вы начинаете перетаскивать виджет, также запускается onTap самого внешнего контейнера, в результате чего фон на мгновение становится зеленым. Настройки HitTestBehavior.opaque
не работают так, как я ожидал. Также не добавляется обработчик для onTapDown к виджету в стеке.
Итак, как я могу предотвратить запуск onTapDown на самом внешнем GestureDetector, когда пользователь взаимодействует с виджетом внутри стека?
Обновление:
Еще более простой пример проблемы, с которой я сталкиваюсь:
GestureDetector(
onTapDown: (_) {
print("Green");
},
child: Container(
color: Colors.green,
width: 300.0,
height: 300.0,
child: Center(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (_) {
print("Red");
},
child: Container(
color: Colors.red,
width: 50.0,
height: 50.0,
),
),
),
),
);
Когда я касаюсь и удерживаю красный контейнер, печатаются и «Красный», и «Зеленый», даже если внутренний GestureDetector имеет HitTestBehavior.opaque
.