Flutter Drag and Drop Basics Learn how to create an interactive drag-and-drop UI in Flutter. 442 words. By Jeff Delaney Created Apr 30, 2019 Last Updated Apr 30, 2019 Code Slack #flutter The following lesson will teach you how to build a simple drag-and-drop UI with the Draggable and DragTarget widgets. The demo app is a kid’s game (ages 2 to 4) that requires the user to drag a fruit emoji 🍋 from the left column to the matching color on the right. If successfully dropped it will mark that item complete ✅ and the score will increase by one. The user can also reset the game at any time by pressing on the floating action button. Initial Setup In most cases, you will need your widgets organized within a StatefulWidget to render changes to the UI when certain drag/drop events take place. file_type_dartlang main.dart class DragScreen extends StatefulWidget { DragScreen({Key key}) : super(key: key); createState() => ColorGameState(); } class DragScreenState extends State<DragScreen> { @override Widget build(BuildContext context) { return Scaffold( body: Row( children: [ Column( // draggable widgets here ), Column( // droppable widgets here ) ], ), ); } } How to Drag Widgets Draggble There are three different visual states to consider when building a draggable widget. child - This is the child that is initially present. childWhenDragging - This is the widget that gets left behind after user starts dragging. feedback - This is the widget that moves or sticks to the user’s finger. It may be identical to the child, or you may want to add some extra shadow to increase the realism of movement. The different parts of a Draggable widget after the user starts dragging file_type_dartlang main.dart Draggable( data: // optional data to send to the drag target in next step, child: // widget feedback: // widget childWhenDragging: // widget ); How to Drop Widgets DragTarget Now that we have a Draggable widget, we need to give it a “drop zone” using the DragTarget widget. It provides a builder function that gives you access to both the incoming and rejected data. There are several functions that can be used to listen to the various drag/drop events: builder constructs the UI for the DragTarget. onWillAccept fires when the user starts hovering, it must return a boolean to decide whether or not the user can drop the widget here. onAccept fires when the user drops and onWillAccept returns true. onLeave fires if the user leaves without dropping or onWillAcccept returns false; file_type_dartlang main.dart // Prop on StatefulWidget bool successfulDrop; // Used inside build method DragTarget<String>( builder: (BuildContext context, List<String> incoming, List rejected) { if (successfulDrop == true) { return Text('Dropped!') } else { return Text('Empty dropzone'); } }, onWillAccept: (data) => data == 'GOOD', onAccept: (data) { setState(() { successfulDrop = true; }); }, onLeave: (data) { }, );