Flutter Drag & Drop Gridview : Flutter Build Reorderable GridView UI
Published January 10, 2023In this flutter example we will learn how to build a simple drag-and-drop UI inside Gridview. How to make drag and drop from Flutter Grid. Drag and drop is important interaction in mobile apps. Flutter provided a widget called Draggable widget. We can also create custom widgets to make drag and drop interaction in side application. Here we are using a library which will be make drag and drop feature inside Gridview widgets.
Let implement Drag and Drop with Gridview
1. Create a flutter application with any flutter supported IDE
2. Add nine_grid_view library inside pubspec.yaml file
dependencies: flutter: sdk: flutter nine_grid_view: ^2.0.0 |
NineGridView
Similar to Weibo dynamics, WeChat circle of friends, nine grid view controls to display pictures. Support single big picture preview.
It also supports WeChat group , DingTalk group, QQ group avatar effects.
DragSortView
Similar to Weibo/WeChat release dynamic picture selection nine grid view. Support press to enlarge effect, drag and drop sorting, drag and drop to a specified location to delete
3. In this example we are creating a Grid of Numbers and make them drag and drop feature. For this we are using the DragSortView widget.
This widget has different properties which will use to make drag the child widgets. To pass the data to Grid we need a data models which should be a type of DragBean type.
Constructor of DragSortView
DragSortView( this.data, { Key? key, this.width, this.space = 5, this.padding = EdgeInsets.zero, this.margin = EdgeInsets.zero, required this.itemBuilder, required this.initBuilder, this.onDragListener, }) |
final List<DragBean> data; /// View width. final double? width; /// The number of logical pixels between each child. final double space; /// View padding. final EdgeInsets padding; /// View margin. final EdgeInsets margin; /// Called to build children for the view. final IndexedWidgetBuilder itemBuilder; /// Called to build init children for the view. final WidgetBuilder initBuilder; /// On drag listener. final OnDragListener? onDragListener;
So let create a Bean class of Number type
class NumberBean extends DragBean { NumberBean({ this.title, }); /// origin picture file path. String? title; } |
4. Now add DragSortView to our widget class and pass the data to its parameter.
DragSortView( list, space: 5, margin: EdgeInsets.all(20), padding: EdgeInsets.all(0), itemBuilder: (BuildContext context, int index) { return Card( elevation: 5, shadowColor: Colors.blueAccent, color: Colors.redAccent, child: Center(child: Text("${(list[index] as NumberBean).title}",style: TextStyle(fontSize: 40),)), ); }, onDragListener: (MotionEvent event, double itemWidth) { switch (event.action) { case MotionEvent.actionDown: moveAction = event.action!; setState(() {}); break; case MotionEvent.actionMove: double x = event.globalX! + itemWidth; double y = event.globalY! + itemWidth; double maxX = MediaQuery.of(context).size.width - 1 * 100; double maxY = MediaQuery.of(context).size.height - 1 * 100; print('Sky24n maxX: $maxX, maxY: $maxY, x: $x, y: $y'); if (_canDelete && (x < maxX || y < maxY)) { setState(() { _canDelete = false; }); } else if (!_canDelete && x > maxX && y > maxY) { setState(() { _canDelete = true; }); } break; case MotionEvent.actionUp: moveAction = event.action!; if (_canDelete) { setState(() { _canDelete = false; }); return true; } else { setState(() {}); } break; } return false; }, initBuilder: (BuildContext context) { return SizedBox.shrink(); }, ), |
5. Now run the application on any device/emulator and you can able to do the Items drag and drop inside gridview.
![]() |
![]() |
Complete code will be like below
import 'package:flutter/material.dart'; import 'package:nine_grid_view/nine_grid_view.dart'; void main() { runApp( MyHomePage(title: 'Flutter Gridview Drag&Drop')); } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { List<DragBean>list=List.empty(growable: true); int moveAction = MotionEvent.actionUp; bool _canDelete = false; @override void initState() { // TODO: implement initState super.initState(); list.add(NumberBean(title: "1")); list.add(NumberBean(title: "2")); list.add(NumberBean(title: "3")); list.add(NumberBean(title: "4")); list.add(NumberBean(title: "5")); list.add(NumberBean(title: "6")); list.add(NumberBean(title: "7")); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( // Here we take the value from the MyHomePage object that was created by // the App.build method, and use it to set our appbar title. title: Text(widget.title), ), body: ListView( children: [ DragSortView( list, space: 5, margin: EdgeInsets.all(20), padding: EdgeInsets.all(0), itemBuilder: (BuildContext context, int index) { return Card( elevation: 5, shadowColor: Colors.blueAccent, color: Colors.redAccent, child: Center(child: Text("${(list[index] as NumberBean).title}",style: TextStyle(fontSize: 40),)), ); }, onDragListener: (MotionEvent event, double itemWidth) { switch (event.action) { case MotionEvent.actionDown: moveAction = event.action!; setState(() {}); break; case MotionEvent.actionMove: double x = event.globalX! + itemWidth; double y = event.globalY! + itemWidth; double maxX = MediaQuery.of(context).size.width - 1 * 100; double maxY = MediaQuery.of(context).size.height - 1 * 100; print('Sky24n maxX: $maxX, maxY: $maxY, x: $x, y: $y'); if (_canDelete && (x < maxX || y < maxY)) { setState(() { _canDelete = false; }); } else if (!_canDelete && x > maxX && y > maxY) { setState(() { _canDelete = true; }); } break; case MotionEvent.actionUp: moveAction = event.action!; if (_canDelete) { setState(() { _canDelete = false; }); return true; } else { setState(() {}); } break; } return false; }, initBuilder: (BuildContext context) { return SizedBox.shrink(); }, ), ], ) // This trailing comma makes auto-formatting nicer for build methods. ), ); } } class NumberBean extends DragBean { NumberBean({ this.title, }); /// origin picture file path. String? title; } |
Article Contributed By :
|
|
|
|
866 Views |