Drag and Drop using Draggable and DragTarget in Flutter

Hemant M
4 min readJul 2, 2021

--

Flutter community is growing with great speed. We are getting pretty impressive widgets every week, 2 of them are Draggable and DragTarget.

Drag and Drop

As the name suggests Draggable and DragTarget need to use together to archive, drag and drop functionality. With this drag and drop, what is actually happening behind the scene is data sharing. For drag and drop to be successful the data which is been shared among this 2 widgets suppose to be of same type.

Let’s jump into the details of each widget.

Draggable

In below example below, we see a SkyBlueCoin() A widget which is set as child i.e. The default widget. When we try to drag SkyBlueCoin() widget the PinkCoin() widget will take it’s place which is set as childWhenDragging , and the widget which we will be dragging is DarkRedCoin() widget which is set as feedback. The data contains the information that will be dropped by this draggable.

To use Draggable we need to understand following parameters :

  1. child: This widget will be visible when there is no dragging.
  2. childWhenDragging: This widget will be visible in place of child widget at the time of dragging.
  3. feedback: When dragging is underway, This is the widget which we will be dragging.
  4. data: It contains the information which we want to drop into DragTarget widget.

The Draggable class provides following callback functions:

  1. onDragStarted: Called when the Draggable starts being dragged.
  2. onDragEnd: Called when the Draggable is dropped.
  3. onDragCompleted: Called when the Draggable is dropped and accepted by a DragTarget.
  4. onDraggableCanceled: Called when the Draggable is dropped without being accepted by a DragTarget.
  5. onDragUpdate: Called when the draggable is being dragged.

Let’s start the Dragging out topic to DragTarget which is the receiver or destination for the Draggable widget.

DragTarget

In the example below, we can see UI for DragTarget is handled inside builder . onWillAccept show the condition when the DragTarget is interested in receiving a given piece of data. In our example the DragTarget will accept all data, if data type of dragged data is of int type. onAccept will be called every time when DragTarget receives data.

The builder property can Identify that is user is dragging some data over DragTarget or not with the help of candidateData & rejectedData.

To use Draggable we need to understand following parameters and callback functions:

  1. builder: Called to build the contents of this widget.
  2. onWillAccept: Called to determine whether this widget is interested in receiving a given piece of data being dragged over this drag target.
  3. onAccept: Called when an acceptable piece of data was dropped over this DragTarget.
  4. onAcceptWithDetails: Called when an acceptable piece of data was dropped over this DragTarget. This callback is Equivalent to onAccept, but with information, including the data, in a DragTargetDetails.
  5. onLeave: Called when a given piece of data being dragged over this target leaves the target.
  6. onMove: Called when a Draggable moves within DragTarget.

Let’s see an simple example for better understanding of Draggable & DragTarget.

  • Line 13: First we are setting a bool variable isDroppedOnDropTarget as false, to indicate DragTarget do not have any data dropped in it yet.
  • Line 21: We are adding Draggable Widget in widget tree which has the following parameters — child, childWhenDragging, feedback, data. Draggable widget will carry int type data.
  • Line 22: child widget will be visible when zero drags are under way i.e. SkyBlueCoin().
  • Line 23: feedback widget will be visible under the pointer when a drag is under way i.e. DarkRedCoin().
  • Line 24: childWhenDragging widget to display instead of child widget when one or more drags are under way.
  • Line 25: data is the information that will be carried by this Draggable.
  • Line 28: We are adding DragTarget of int type in widget tree. DragTarget will have following parameters —builder , onWillAccept, onAccept.
  • Line 29: The builder returns widget which will be visible in DragTarget. The values passed to builder start changing if Draggable is hovered over the DragTarget or is dropped onto it.

builder has 3 parameters context, candidateData and rejectedData.

The candidateData is the data of a which is being dragged over the DragTarget, acceptable to that DragTarget.

The rejectedData is the data which is being dragged over the DragTarget , but not acceptable by that DragTarget..

  • Line 30: here we are returning widget which should be visible by DragTarget . we are using Ternary Operators to return which widget should be visible.

If no data are dropped yet into DragTarget then builder will return BlueCoin() widget or RedCoin() widget depending on if acceptable data is been hovered over DragTarget or not. Once we drop any data in DragTarget then only PurpleCoin() widget will be returned by builder.

  • Line 36: onWillAccept will indicate at which condition the DragTarget will accept the dropped data if the data is of acceptable type. In the above example, we will accept any dropped data as long as data type matches by setting onWillAccept: (value) => true,
  • Line 37: onAccept get called whenever an acceptable piece of data is dropped over DragTarget. We will set isDroppedOnDropTarget to true in onAccept .

For depth understanding check out following project.

You can check this project’s code here.

--

--