How to move element anywhere inside parent container with drag and drop in Flutter?
Just ran into the same problem working on a drag-and-drop canvas in Flutter Web. I ended up working around this by inserting a GlobalKey for each of the draggable widgets and adjusting the placement offsets by accounting for the size of the containing renderbox (after waiting for the rendering to complete, via the addPostFrameCallback()). In order to facilitate precise placement, I used a Stack()/Positioned() and placed the Draggable() within this:
import 'package:flutter/material.dart';
class PositionedDraggableIcon extends StatefulWidget {
final double top;
final double left;
PositionedDraggableIcon({Key key, this.top, this.left}) : super(key: key);
@override
_PositionedDraggableIconState createState() => _PositionedDraggableIconState();
}
class _PositionedDraggableIconState extends State<PositionedDraggableIcon> {
GlobalKey _key = GlobalKey();
double top, left;
double xOff, yOff;
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
top = widget.top;
left = widget.left;
super.initState();
}
void _getRenderOffsets() {
final RenderBox renderBoxWidget = _key.currentContext.findRenderObject();
final offset = renderBoxWidget.localToGlobal(Offset.zero);
yOff = offset.dy - this.top;
xOff = offset.dx - this.left;
}
void _afterLayout(_) {
_getRenderOffsets();
}
@override
Widget build(BuildContext context) {
return Positioned(
key: _key,
top: top,
left: left,
child: Draggable(
child: Icon(Icons.input),
feedback: Icon(Icons.input),
childWhenDragging: Container(),
onDragEnd: (drag) {
setState(() {
top = drag.offset.dy - yOff;
left = drag.offset.dx - xOff;
});
},
),
);
}
}
It's probably possible to do this with the widget context itself and avoid the GlobalKey, but this works well enough for me.
Peyman
Updated on December 12, 2022Comments
-
Peyman over 1 year
I'm using the Draggable widget in Flutter, and I want to move my element anywhere inside a parent widget.
I tried the dragtarget widget, but I couldn't set it to my parent widget. I also tried the
onDraggableCanceled
method of the Draggable widget for getting the offset, and applied it for the new offset of the element, but it gives me the offset from the device, not from the parent container.So, what is the right way of doing this?
-
jkdev almost 5 yearsWelcome to Stack Overflow! Could you please post the specific code that you are using?
-
-
Jhon Charles about 2 yearsIs it possible to accomplish the same thing but using onDragUpdate?. I would like to avoid the element leaving the parent at all.