Skip to content

Instantly share code, notes, and snippets.

@augustl
Last active February 7, 2019 21:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save augustl/b6990dae3881933e8356c70fa9bd6b85 to your computer and use it in GitHub Desktop.
Save augustl/b6990dae3881933e8356c70fa9bd6b85 to your computer and use it in GitHub Desktop.
class MyDraggable extends StatefulWidget {
final Widget child;
final Widget childWhenDragging;
final Widget feedback;
final VoidCallback onDragEnd;
MyDraggable({
@required this.child,
@required this.childWhenDragging,
@required this.feedback,
this.onDragEnd
});
@override
State createState() {
return MyDraggableState();
}
}
class MyDraggableState extends State<MyDraggable> {
OverlayEntry _dragOoverlayEntry;
Offset _dragPosition;
bool _isDragging = false;
void _setIsDragging(bool isDragging) {
setState(() {
_isDragging = isDragging;
});
}
@override
Widget build(BuildContext context) {
return GestureDetector(
child: _isDragging ? this.widget.childWhenDragging : this.widget.child,
onPanStart: (e) {
_setIsDragging(true);
_dragPosition = e.globalPosition;
final overlayState = Overlay.of(context);
_dragOoverlayEntry = OverlayEntry(builder: _buildOverlayEntry);
overlayState.insert(_dragOoverlayEntry);
},
onPanUpdate: (e) {
_dragPosition += e.delta;
_dragOoverlayEntry.markNeedsBuild();
},
onPanCancel: () {
this._stopDragging();
},
onPanEnd: (e) {
this._stopDragging();
},
);
}
Widget _buildOverlayEntry(BuildContext context) {
return Positioned(
left: _dragPosition.dx,
top: _dragPosition.dy,
child: this.widget.feedback);
}
void _stopDragging() {
if (this.widget.onDragEnd != null) {
this.widget.onDragEnd();
}
_setIsDragging(false);
if (_dragOoverlayEntry != null) {
_dragOoverlayEntry.remove();
_dragOoverlayEntry = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment