How do you implement a draggable widget in flutter?
#widget#draggable#gestures
Answer
Overview
Flutter provides two primary ways to implement draggable widgets: the /textDraggable system for drag-and-drop, and textDragTarget
text
GestureDetector1. Draggable + DragTarget
Use this for drag-and-drop between specific targets.
dartclass DragDropExample extends StatefulWidget { _DragDropExampleState createState() => _DragDropExampleState(); } class _DragDropExampleState extends State<DragDropExample> { Color _targetColor = Colors.grey[300]!; Widget build(BuildContext context) { return Column( children: [ // The draggable item Draggable<Color>( data: Colors.blue, // Data to pass to the target feedback: Container( width: 80, height: 80, decoration: BoxDecoration( color: Colors.blue.withOpacity(0.7), shape: BoxShape.circle, ), ), childWhenDragging: Opacity( opacity: 0.3, child: Container(width: 80, height: 80, color: Colors.blue), ), child: Container(width: 80, height: 80, color: Colors.blue), ), SizedBox(height: 100), // The drop target DragTarget<Color>( onAcceptWithDetails: (details) { setState(() => _targetColor = details.data); }, builder: (context, candidateData, rejectedData) { return Container( width: 120, height: 120, color: candidateData.isNotEmpty ? Colors.green[100] // Highlight when hovering : _targetColor, child: Center(child: Text('Drop here')), ); }, ), ], ); } }
2. GestureDetector (Free-form Drag)
Use this for free movement of a widget anywhere on screen.
dartclass FreeDragWidget extends StatefulWidget { _FreeDragWidgetState createState() => _FreeDragWidgetState(); } class _FreeDragWidgetState extends State<FreeDragWidget> { Offset _position = Offset(100, 100); Widget build(BuildContext context) { return Stack( children: [ Positioned( left: _position.dx, top: _position.dy, child: GestureDetector( onPanUpdate: (details) { setState(() => _position += details.delta); }, child: Container( width: 80, height: 80, decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(12), ), child: Center( child: Text('Drag me', style: TextStyle(color: Colors.white)), ), ), ), ), ], ); } }
3. LongPressDraggable
Like
text
DraggabledartLongPressDraggable<String>( data: 'item_data', feedback: Material( elevation: 4, child: Container( width: 200, height: 60, color: Colors.blue[100], child: Text('Dragging...'), ), ), child: ListTile(title: Text('Long press to drag')), )
When to Use Which
| Use Case | Widget |
|---|---|
| Drag item to a specific drop zone | text text |
| Free movement anywhere | text text |
| Reorderable list | text |
| Drag to activate after hold | text |