Jérémie Laval Jérémie Laval February 25, 2013 ,

Since Honeycomb, Android has offered a very straightforward, easy-to-use API for implementing drag and drop in your application. Any View can be dragged and any other View can become a drop zone. You can attach information to a drag operation to be used by the receiver, allowing the application to do more processing when a drop is performed.

The core of the API for drop zones is built around one event and several states. To declare a drop zone in Mono for Android, you simply need to attach a handler to the Drag event of your view (the same handler can be reused).

That handler will receive a View.DragEventArgs as a parameter. It will have an e.Event.Action property that specifies the state of the current drag process. The following is one simple implementation of the method as a state machine, with a comment on each section to describe the nature of the state:

To initiate the drag and tell which View is being dragged, you use the StartDrag method on it. Generally, this is done as part of a Click event handler (but anything else will do). This is also when you create the data that you want to associate with the drag:

StartDrag takes as parameters your drag data, a shadow builder (more on that in a sec), a state object (if you want one), and a set of flags (which are currently unused and should always be 0).

The interesting tidbit is the View.DragShadowBuilder parameter, which lets you personalize the look of the drag shadow. By default, you can supply an instance of the class and pass in your view to create a default drag shadow. That approach will essentially be an image snapshot of your view with some transparency—which is actually fine for most cases. Of course, what’s more interesting is that you can create entirely custom drag shadows:


It’s actually pretty simple to do so, as it’s very similar to normal View painting. First, you need to create your own class deriving from View.DragShadowBuilder. Your constructor should take the dragged View and pass it down to the base constructor.

The two methods you then need to implement are OnProvideShadowMetrics and OnDrawShadow. In the first one, you will give the measurements of your drag shadow. In the second, you will be given a Canvas in which to draw your shadow.

Here is my implementation of the drag shadow builder that produces the image above (with inline explanations):

On a final note, you will notice that I’m painting the dragged View at the end of my OnDrawShadow method using the DrawingCache property. For that property to return something valid, you need to set the DrawingCacheEnabled property to true on the view.