Flutter: Drag and drop with Grid
You can also try this easier one (It doesn't include Feedback)
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp(home: Scaffold(body: HomePage())); }}class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState();}class _HomePageState extends State<HomePage> { Offset offset = Offset.zero; @override Widget build(BuildContext context) { return Stack( children: <Widget>[ Positioned( left: offset.dx, top: offset.dy, child: GestureDetector( onPanUpdate: (details) { setState(() { offset = Offset(offset.dx + details.delta.dx, offset.dy + details.delta.dy); }); }, child: Container(width: 100, height: 100, color: Colors.blue), ), ), ], ); }}
Although this may not answer your question but people who are looking for simple drag and drop widget, then here is the example.
See my 2nd answer for more simpler way
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text("Drag app"), ), body: HomePage(), ), ); }}class HomePage extends StatefulWidget { @override State<StatefulWidget> createState() { return _HomePageState(); }}class _HomePageState extends State<HomePage> { double width = 100.0, height = 100.0; Offset position ; @override void initState() { super.initState(); position = Offset(0.0, height - 20); } @override Widget build(BuildContext context) { return Stack( children: <Widget>[ Positioned( left: position.dx, top: position.dy - height + 20, child: Draggable( child: Container( width: width, height: height, color: Colors.blue, child: Center(child: Text("Drag", style: Theme.of(context).textTheme.headline,),), ), feedback: Container( child: Center( child: Text("Drag", style: Theme.of(context).textTheme.headline,),), color: Colors.blue[300], width: width, height: height, ), onDraggableCanceled: (Velocity velocity, Offset offset){ setState(() => position = offset); }, ), ), ], ); }}
I've created a package called reorderables that solved this problem. You just need to tell the package your function to be called when drag and drop is done onReorder(int oldIndex, int newIndex)
.
This example has 9 icon widgets in a grid -Screenshot: ReorderableWrap
class _WrapExampleState extends State<WrapExample> { final double _iconSize = 90; List<Widget> _tiles; @override void initState() { super.initState(); _tiles = <Widget>[ Icon(Icons.filter_1, key: ValueKey(1), size: _iconSize), Icon(Icons.filter_2, key: ValueKey(2), size: _iconSize), Icon(Icons.filter_3, key: ValueKey(3), size: _iconSize), Icon(Icons.filter_4, key: ValueKey(4), size: _iconSize), Icon(Icons.filter_5, key: ValueKey(5), size: _iconSize), Icon(Icons.filter_6, key: ValueKey(6), size: _iconSize), Icon(Icons.filter_7, key: ValueKey(7), size: _iconSize), Icon(Icons.filter_8, key: ValueKey(8), size: _iconSize), Icon(Icons.filter_9, key: ValueKey(9), size: _iconSize), ]; } @override Widget build(BuildContext context) { void _onReorder(int oldIndex, int newIndex) { setState(() { Widget row = _tiles.removeAt(oldIndex); _tiles.insert(newIndex, row); }); } return ReorderableWrap( spacing: 8.0, runSpacing: 4.0, padding: const EdgeInsets.all(8), children: _tiles, onReorder: _onReorder ); }}
If you want to limit the number of columns, you can use an optional parameter named maxMainAxisCount