Since Honeycomb, Android sports a very straightforward and easy to use API to do drag’n drop in your application.
Any View can be dragged and any other View can become a drop zone. You can attach information to your drag to be used by the receiver to do more processing afterwards.
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 an handler to the Drag event of your view (the same handler can be reused).
That handler will receive an View.DragEventArgs as a parameter where the important parameter will be its e.Event.Action property telling in which state the current drag process is with respect to you.
Following is one simple implementation of the method as a state machine with 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 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 flag although right now they are unused (hence it should always be 0).
The interesting tidbit is the View.DragShadowBuilder parameter that lets you personalize the look of the drag shadow.
By default you can supply an instance of the class passing in your view to create a default drag shadow that will essentially be an image snapshot of your view with some transparency.
This mode is actually fine for most cases if you don’t want to bother.
Of course, what’s more interesting is that you can create your 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 and in the second, you will be given a Canvas to draw your shadow in.
Here is my implementation of the drag shadow builder that produces the image above (with inline explanations):
On a last 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.