The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.
Desktop applications have long offered drag-and-drop, both within and between applications. Android has supported this for quite some time, but you could only drag and drop within a single activity. As a result, this was not especially popular.
However, starting in Android 7.0, you can drag and drop between applications, so long as their windows are visible in a multi-window environment. Not only does this make drag-and-drop more compelling in general, but in a freeform multi-window environment, users will expect Android apps to behave like their desktop counterparts. Hence, users will expect drag-and-drop capabilities where it makes sense.
In this chapter, we will explore Android’s drag-and-drop facility, including how to perform it between separate applications.
Understanding this chapter requires that you have read the core chapters of this book, as well as the chapter on the clipboard.
One example uses
RecyclerView, so reviewing
that chapter is a good idea. Similarly, one sample
StreamProvider, so you may wish to read the section on it
Since the term “drag-and-drop” means different things to different people – including different developers used to different platforms — it will help if we understand exactly what Android’s definition of “drag-and-drop” is.
In Android, the focus is on dragging and dropping content, meaning some
information identified by a
Uri and an associated MIME type. We
are using the drag-and-drop process to select some piece of content
and inform something else about that content. Specifically, the
content that we are dragging and dropping is represented by a
object, the same as we could use with the clipboard.
ClipData does not have to represent content. The
clipboard supports plain text
ClipData items, and nothing is stopping
you from using drag and drop for plain text as a result. When dragging
and dropping between apps, this may cause some compatibility issues,
though the drag-and-drop framework takes steps to help deal with this.
Within an app, options like plain text allow you to “cheat” to an extent,
allowing drag-and-drop to support anything you want, so long as you can
identify the specific “anything you want” by a string ID or key.
From the user’s standpoint, the user is dragging some visual representation of this content. That can be whatever bitmap you want, and you will have a few options for specifying what this bitmap is. This bitmap is referred to as the “shadow”.
You will need to provide some UI that triggers a drag-and-drop operation, not only allowing the user to say “let’s drag this somewhere” but also “here is what ‘this’ I want to drag”.
A typical trigger for this is a long-click. So, for example, a long-click on a list row might trigger a drag-and-drop of the content identified by that row.
Usually, the trigger is tied to some view, as drag-and-drop intrinsically is a visual operation. Technically, this is not required, if you can find some other approach that users will understand and appreciate.
You will need to identify possible drop targets, in the form of views. A view can be registered as a potential drop target, then stipulate whether it is a candidate for a specific drag-and-drop operation when that operation begins. For example, if you have two lists, and you want the user to drag items between the lists, both are potential drop targets. However, you might elect to say that the user cannot drag from a list back into that same list, so if the content being dragged originated from the list, that list is not a candidate for that specific drag-and-drop operation.
The preview of this section was abducted by space aliens.
The preview of this section was stepped on by Godzilla.
The preview of this section was the victim of a MITM ('Martian in the middle') attack.
The preview of this section was lost in the sofa cushions.
The preview of this section will not appear here for a while, due to a time machine mishap.
The preview of this section was last seen in the Bermuda Triangle.
The preview of this section was eaten by a grue.
The preview of this section is presently indisposed.
The preview of this section is [REDACTED].
The preview of this section is sleeping in.
The preview of this section is sleeping in.