Adding Drag and Drop to your Android application with Xamarin

Since touchscreens have conquered our everyday life, drag and drop functionality accompanies us on our way through the digital world. The simplicity of this intuitive design pattern is responsible for its success story. This is why you should enhance you applications by implementing it. And this is easier than you might have thought.

Drag and Drop is part of the Android API since Honeycomb and any View element can be dragged, dropped or work as a drop zone for others. To do so, no additional UI work is needed, you just attach the right events and fire the right methods in your code and you are done. But let’ start at the beginning.

XamarinDragAndDropDemo

The UI Layout

For the demo you can see on the right I have just createdtwo buttons that can be dragged and dropped to the gray drop zone at the top of the page.As mentioned above, every View element can be dragged or work as a drop zone so that the UI plays no special part in it and I won’t go into it. If you need more detailed information about the shown layout, please check the Sample Code.

The Code

Two stepsin your code bring you closerto the Drag and Drop implementation: Enabling elements to be dragged and dropped and defining drop zones. We will begin with the former.

First you need to choose an event on whichthe dragging should start. In my demo this is along click on one of the buttons. Inside this event you can start the dragging procedure by simply calling the StartDrag() method on your element. It accepts a ClipData element, a DragShadowBuilder instance, a local stateand a status flag as parameters, so let’s take a short look at them.While we can forget the last two for the moment, the ClipData and DragShadowBuilder might be important for us.

ClipData is the only way to provide additional information to the dragged element. When the user drops it later, we can not identify which element got dropped. The only thing we can access is the attached data. So it might be clever to add some kind of identifier here.

The DragShadowBuilder is responsible for generating the drag shadow for the current element. By default this is a half translucent copy which should be good enoughfor most usecases. If you need something else, you can define your own one. You can find further information about that here.

void Button1_LongClick (object sender, View.LongClickEventArgs e)
{
	// Generate clip data package to attach it to the drag
	var data = ClipData.NewPlainText("name", "Element 1");

	// Start dragging and pass data
	((sender) as Button).StartDrag(data, new View.DragShadowBuilder(((sender) as Button)), null, 0);
}

To define a drop zone, you simply need to listen to the drop zone’s Drag event by adding an according event handler to it. Here you can differ between the Drag and Drop actions that can occur:

DragAction.Ended and DragAction.Started mark the begin and end of the dragging process and just need to be marked as handled.DragAction.Entered and DragAction.Exited actions occur whenever a dragged element enters or exits the drop zone. We coulddo some fancy UI stuff here like showing a drop hint.The one that is clearly most important for us is the DragAction.Drop action. Here we can decide whether to accept the drop and try to get the attached ClipData to do some further actions with it.

void Button_Drag (object sender, View.DragEventArgs e)
{
	// React on different dragging events
	var evt = e.Event;
	switch (evt.Action) 
	{
		case DragAction.Ended:  
		case DragAction.Started:
			e.Handled = true;
			break;           
			
		// Dragged element enters the drop zone
		case DragAction.Entered:                   
			result.Text = "Drop it like it's hot!";
			break;
			
		// Dragged element exits the drop zone
		case DragAction.Exited:                   
			result.Text = "Drop something here!";
			break;
			
		// Dragged element has been dropped at the drop zone
		case DragAction.Drop:
			// You can check if element may be dropped here
			// If not do not set e.Handled to true
			e.Handled = true;

			// Try to get clip data
			var data = e.Event.ClipData;
			if (data != null)
				result.Text = data.GetItemAt(0).Text + " has been dropped.";                    
			break;
	}
}

Conclusion

It is really fast and super easy to implement a basic Drag and Drop functionality in your Android application which provides a nice way to enhance your user experience where it makes sense. The latter is very important – not only if you want to add Drag and Drop but whenever you plan to add new UI functionality to you application: Make sure that it makes sense at the place where you want to add it and that it brings a benefit to your users.

If you are sure about this, you can implement it a very clean and simple way without much code overhead. And that is all we wanted, isn’t it?

For a working demo feel free to take a look at our Sample Code.