I want to have 2 movable widgets in a flutter's stack. I created a stack with red and blue containers, wrapped with GestureDetector and Positioned and they moved well.
when I tried to have the item that is touched on top of the other, I got a phenoment that when I try moving the red container, the blue actually moves, and in the code below, I get the first printing onPanStart:red, followed by the printing:blue is moved If i first touch the element I want to move, and only then moves it, it moves ok
note, that my original problem had a list of widgets in the stack, in this example, I narrowed it down to 2 basic elements.
why is the wrong elemnt moves?
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Draggable Containers with Z-Order',
home: Scaffold(
appBar: AppBar(title: Text('Draggable Containers with Z-Order')),
body: DraggableStack(),
),
);
}
}
class DraggableStack extends StatefulWidget {
@override
_DraggableStackState createState() => _DraggableStackState();
}
class _DraggableStackState extends State<DraggableStack> {
// Starting positions for the containers.
Offset redPosition = Offset(50, 50);
Offset bluePosition = Offset(200, 200);
// True if red container is on top, false if blue container is on top.
bool redOnTop = false;
@override
Widget build(BuildContext context) {
// Create the red container widget.
Widget redContainer = Positioned(
left: redPosition.dx,
top: redPosition.dy,
child: GestureDetector(
onPanStart: (_) {
setState(() {
redOnTop = true;
print("onPanStart:red");
});
},
onPanUpdate: (details) {
setState(() {
redPosition += details.delta;
print("red is moved");
});
},
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
);
// Create the blue container widget.
Widget blueContainer = Positioned(
left: bluePosition.dx,
top: bluePosition.dy,
child: GestureDetector(
onPanStart: (_) {
setState(() {
redOnTop = false;
print("onPanStart:blue");
});
},
onPanUpdate: (details) {
setState(() {
bluePosition += details.delta;
print("blue is moved");
});
},
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
);
// Render the Stack so that the touched container is above.
return Stack(
children: redOnTop
? [blueContainer, redContainer] // Red on top.
: [redContainer, blueContainer], // Blue on top.
);
}
}
