995 lines
44 KiB
Plaintext
995 lines
44 KiB
Plaintext
|
page.title=Dragging and Dropping
|
||
|
@jd:body
|
||
|
<div id="qv-wrapper">
|
||
|
<div id="qv">
|
||
|
<h2>Quickview</h2>
|
||
|
<ul>
|
||
|
<li>
|
||
|
Allow users to move data within your Activity layout using graphical gestures.
|
||
|
</li>
|
||
|
<li>
|
||
|
Supports operations besides data movement.
|
||
|
</li>
|
||
|
<li>
|
||
|
Only works within a single application.
|
||
|
</li>
|
||
|
<li>
|
||
|
Requires API 11.
|
||
|
</li>
|
||
|
</ul>
|
||
|
<h2>In this document</h2>
|
||
|
<ol>
|
||
|
<li>
|
||
|
<a href="#AboutDragging">Overview</a>
|
||
|
<ol>
|
||
|
<li>
|
||
|
<a href="#DragDropLifecycle">The drag/drop process</a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#AboutDragListeners">The drag event listener and callback method</a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#AboutDragEvent">Drag events</a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#AboutDragShadowBuilder">
|
||
|
The drag shadow</a>
|
||
|
</li>
|
||
|
</ol>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>
|
||
|
<ol>
|
||
|
<li>
|
||
|
<a href="#StartDrag">Starting a drag</a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#HandleStart">Responding to a drag start</a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#HandleDuring">Handling events during the drag</a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#HandleDrop">Responding to a drop</a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#HandleEnd">Responding to a drag end</a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="#RespondEventSample">Responding to drag events: an example</a>
|
||
|
</li>
|
||
|
</ol>
|
||
|
</li>
|
||
|
</ol>
|
||
|
<h2>Key classes</h2>
|
||
|
<ol>
|
||
|
<li>
|
||
|
{@link android.view.View View}
|
||
|
</li>
|
||
|
<li>
|
||
|
{@link android.view.View.OnLongClickListener OnLongClickListener}
|
||
|
</li>
|
||
|
<li>
|
||
|
{@link android.view.View.OnDragListener OnDragListener}
|
||
|
</li>
|
||
|
<li>
|
||
|
{@link android.view.DragEvent DragEvent}
|
||
|
</li>
|
||
|
<li>
|
||
|
{@link android.view.View.DragShadowBuilder DragShadowBuilder}
|
||
|
</li>
|
||
|
<li>
|
||
|
{@link android.content.ClipData ClipData}
|
||
|
</li>
|
||
|
<li>
|
||
|
{@link android.content.ClipDescription ClipDescription}
|
||
|
</li>
|
||
|
</ol>
|
||
|
<h2>Related Samples</h2>
|
||
|
<ol>
|
||
|
<li>
|
||
|
<a href="{@docRoot}resources/samples/Honeycomb-Gallery/index.html">
|
||
|
Honeycomb-Gallery</a> sample application.
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.html">
|
||
|
DragAndDropDemo.java</a> and
|
||
|
<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DraggableDot.html">
|
||
|
DraggableDot.java</a> in <a href="{@docRoot}resources/samples/ApiDemos/index.html">Api Demos</a>.
|
||
|
</li>
|
||
|
</ol>
|
||
|
<h2>See also</h2>
|
||
|
<ol>
|
||
|
<li>
|
||
|
<a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
|
||
|
</li>
|
||
|
<li>
|
||
|
<a href="{@docRoot}guide/topics/ui/ui-events.html">Handling UI Events</a>
|
||
|
</li>
|
||
|
</ol>
|
||
|
</div>
|
||
|
</div>
|
||
|
<p>
|
||
|
With the Android drag/drop framework, you can allow your users to move data
|
||
|
from one View to another View in the current layout using a graphical drag and drop gesture.
|
||
|
The framework includes a drag event class, drag listeners, and helper methods and classes.
|
||
|
</p>
|
||
|
<p>
|
||
|
Although the framework is primarily designed for data movement, you can use
|
||
|
it for other UI actions. For example, you could create an app that mixes colors when the user
|
||
|
drags a color icon over another icon. The rest of this topic, however, describes the
|
||
|
framework in terms of data movement.
|
||
|
</p>
|
||
|
<h2 id="AboutDragging">Overview</h2>
|
||
|
<p>
|
||
|
A drag and drop operation starts when the user makes some gesture that you recognize as a
|
||
|
signal to start dragging data. In response, your application tells the system that the drag is
|
||
|
starting. The system calls back to your application to get a representation of the data
|
||
|
being dragged. As the user's finger moves this representation (a "drag shadow")
|
||
|
over the current layout, the system sends drag events to the drag event listener objects and
|
||
|
drag event callback methods associated with the {@link android.view.View} objects in the layout.
|
||
|
Once the user releases the drag shadow, the system ends the drag operation.
|
||
|
</p>
|
||
|
<p>
|
||
|
You create a drag event listener object ("listeners") from a class that implements
|
||
|
{@link android.view.View.OnDragListener}. You set the drag event listener object for a View
|
||
|
with the View object's
|
||
|
{@link android.view.View#setOnDragListener(View.OnDragListener) setOnDragListener()} method.
|
||
|
Each View object also has a {@link android.view.View#onDragEvent(DragEvent) onDragEvent()}
|
||
|
callback method. Both of these are described in more detail in the section
|
||
|
<a href="#AboutDragListeners">The drag event listener and callback method</a>.
|
||
|
</p>
|
||
|
<p class="note">
|
||
|
<strong>Note</strong>: For the sake of simplicity, the following sections refer to the routine
|
||
|
that receives drag events as the "drag event listener", even though it may actually
|
||
|
be a callback method.
|
||
|
</p>
|
||
|
<p>
|
||
|
When you start a drag, you include both the data you are moving and metadata describing this
|
||
|
data as part of the call to the system. During the drag, the system sends drag events to the
|
||
|
drag event listeners or callback methods of each View in the layout. The listeners or callback
|
||
|
methods can use the metadata to decide if they want to accept the data when it is dropped.
|
||
|
If the user drops the data over a View object, and that View object's listener or callback
|
||
|
method has previously told the system that it wants to accept the drop, then the system sends
|
||
|
the data to the listener or callback method in a drag event.
|
||
|
</p>
|
||
|
<p>
|
||
|
Your application tells the system to start a drag by calling the
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
|
||
|
method. This tells the system to start sending drag events. The method also sends the data that
|
||
|
you are dragging.
|
||
|
</p>
|
||
|
<p>
|
||
|
You can call
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
|
||
|
for any attached View in the current layout. The system only uses the View object to get access
|
||
|
to global settings in your layout.
|
||
|
</p>
|
||
|
<p>
|
||
|
Once your application calls
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()},
|
||
|
the rest of the process uses events that the system sends to the View objects in your current
|
||
|
layout.
|
||
|
</p>
|
||
|
<h3 id="DragDropLifecycle">The drag/drop process</h3>
|
||
|
<p>
|
||
|
There are basically four steps or states in the drag and drop process:
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt>
|
||
|
<em>Started</em>
|
||
|
</dt>
|
||
|
<dd>
|
||
|
In response to the user's gesture to begin a drag, your application calls
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
|
||
|
to tell the system to start a drag. The arguments
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
|
||
|
provide the data to be dragged, metadata for this data, and a callback for drawing the
|
||
|
drag shadow.
|
||
|
<p>
|
||
|
The system first responds by calling back to your application to get a drag shadow. It
|
||
|
then displays the drag shadow on the device.
|
||
|
</p>
|
||
|
<p>
|
||
|
Next, the system sends a drag event with action type
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_STARTED} to the drag event listeners for
|
||
|
all the View objects in the current layout. To continue to receive drag events,
|
||
|
including a possible drop event, a drag event listener must return <code>true</code>.
|
||
|
This registers the listener with the system. Only registered listeners continue to
|
||
|
receive drag events. At this point, listeners can also change the appearance of their
|
||
|
View object to show that the listener can accept a drop event.
|
||
|
</p>
|
||
|
<p>
|
||
|
If the drag event listener returns <code>false</code>, then it will not receive drag
|
||
|
events for the current operation until the system sends a drag event with action type
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENDED}. By sending <code>false</code>, the
|
||
|
listener tells the system that it is not interested in the drag operation and
|
||
|
does not want to accept the dragged data.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>
|
||
|
<em>Continuing</em>
|
||
|
</dt>
|
||
|
<dd>
|
||
|
The user continues the drag. As the drag shadow intersects the bounding box of a View
|
||
|
object, the system sends one or more drag events to the View object's drag event
|
||
|
listener (if it is registered to receive events). The listener may choose to
|
||
|
alter its View object's appearance in response to the event. For example, if the event
|
||
|
indicates that the drag shadow has entered the bounding box of the View
|
||
|
(action type {@link android.view.DragEvent#ACTION_DRAG_ENTERED}), the listener
|
||
|
can react by highlighting its View.
|
||
|
</dd>
|
||
|
<dt>
|
||
|
<em>Dropped</em>
|
||
|
</dt>
|
||
|
<dd>
|
||
|
The user releases the drag shadow within the bounding box of a View that can accept the
|
||
|
data. The system sends the View object's listener a drag event with action type
|
||
|
{@link android.view.DragEvent#ACTION_DROP}. The drag event contains the data that was
|
||
|
passed to the system in the call to
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
|
||
|
that started the operation. The listener is expected to return boolean <code>true</code> to
|
||
|
the system if code for accepting the drop succeeds.
|
||
|
<p>
|
||
|
Note that this step only occurs if the user drops the drag shadow within the bounding
|
||
|
box of a View whose listener is registered to receive drag events. If the user releases
|
||
|
the drag shadow in any other situation, no {@link android.view.DragEvent#ACTION_DROP}
|
||
|
drag event is sent.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>
|
||
|
<em>Ended</em>
|
||
|
</dt>
|
||
|
<dd>
|
||
|
After the user releases the drag shadow, and after the system sends out (if necessary)
|
||
|
a drag event with action type {@link android.view.DragEvent#ACTION_DROP}, the system sends
|
||
|
out a drag event with action type {@link android.view.DragEvent#ACTION_DRAG_ENDED} to
|
||
|
indicate that the drag operation is over. This is done regardless of where the user released
|
||
|
the drag shadow. The event is sent to every listener that is registered to receive drag
|
||
|
events, even if the listener received the {@link android.view.DragEvent#ACTION_DROP} event.
|
||
|
</dd>
|
||
|
</dl>
|
||
|
<p>
|
||
|
Each of these four steps is described in more detail in the section
|
||
|
<a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>.
|
||
|
</p>
|
||
|
<h3 id="AboutDragListeners">The drag event listener and callback method</h3>
|
||
|
<p>
|
||
|
A View receives drag events with either a drag event listener that implements
|
||
|
{@link android.view.View.OnDragListener} or with its
|
||
|
{@link android.view.View#onDragEvent(DragEvent)} callback method.
|
||
|
When the system calls the method or listener, it passes to them
|
||
|
a {@link android.view.DragEvent} object.
|
||
|
</p>
|
||
|
<p>
|
||
|
You will probably want to use the listener in most cases. When you design UIs, you usually
|
||
|
don't subclass View classes, but using the callback method forces you to do this in order to
|
||
|
override the method. In comparison, you can implement one listener class and then use it with
|
||
|
several different View objects. You can also implement it as an anonymous inline class. To
|
||
|
set the listener for a View object, call
|
||
|
{@link android.view.View#setOnDragListener(android.view.View.OnDragListener) setOnDragListener()}.
|
||
|
</p>
|
||
|
<p>
|
||
|
You can have both a listener and a callback method for View object. If this occurs,
|
||
|
the system first calls the listener. The system doesn't call the callback method unless the
|
||
|
listener returns <code>false</code>.
|
||
|
</p>
|
||
|
<p>
|
||
|
The combination of the {@link android.view.View#onDragEvent(DragEvent)} method and
|
||
|
{@link android.view.View.OnDragListener} is analogous to the combination
|
||
|
of the {@link android.view.View#onTouchEvent(MotionEvent) onTouchEvent()} and
|
||
|
{@link android.view.View.OnTouchListener} used with touch events.
|
||
|
</p>
|
||
|
<h3 id="AboutDragEvent">Drag events</h3>
|
||
|
<p>
|
||
|
The system sends out a drag event in the form of a {@link android.view.DragEvent} object. The
|
||
|
object contains an action type that tells the listener what is happening in the drag/drop
|
||
|
process. The object contains other data, depending on the action type.
|
||
|
</p>
|
||
|
<p>
|
||
|
To get the action type, a listener calls {@link android.view.DragEvent#getAction()}. There
|
||
|
are six possible values, defined by constants in the {@link android.view.DragEvent} class. These
|
||
|
are listed in <a href="table1">table 1</a>.
|
||
|
</p>
|
||
|
<p>
|
||
|
The {@link android.view.DragEvent} object also contains the data that your application provided
|
||
|
to the system in the call to
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}.
|
||
|
Some of the data is valid only for certain action types. The data that is valid for each action
|
||
|
type is summarized in <a href="table2">table 2</a>. It is also described in detail with
|
||
|
the event for which it is valid in the section
|
||
|
<a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>.
|
||
|
</p>
|
||
|
<p class="table-caption" id="table1">
|
||
|
<strong>Table 1.</strong> DragEvent action types
|
||
|
</p>
|
||
|
<table>
|
||
|
<tr>
|
||
|
<th scope="col">getAction() value</th>
|
||
|
<th scope="col">Meaning</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_STARTED}</td>
|
||
|
<td>
|
||
|
A View object's drag event listener receives this event action type just after the
|
||
|
application calls
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()} and
|
||
|
gets a drag shadow.
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_ENTERED}</td>
|
||
|
<td>
|
||
|
A View object's drag event listener receives this event action type when the drag shadow
|
||
|
has just entered the bounding box of the View. This is the first event action type the
|
||
|
listener receives when the drag shadow enters the bounding box. If the listener wants to
|
||
|
continue receiving drag events for this operation, it must return boolean
|
||
|
<code>true</code> to the system.
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_LOCATION}</td>
|
||
|
<td>
|
||
|
A View object's drag event listener receives this event action type after it receives a
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENTERED} event while the drag shadow is
|
||
|
still within the bounding box of the View.
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_EXITED}</td>
|
||
|
<td>
|
||
|
A View object's drag event listener receives this event action type after it receives a
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENTERED} and at least one
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_LOCATION} event, and after the user has moved
|
||
|
the drag shadow outside the bounding box of the View.
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DROP}</td>
|
||
|
<td>
|
||
|
A View object's drag event listener receives this event action type when the user
|
||
|
releases the drag shadow over the View object. This action type is only sent to a View
|
||
|
object's listener if the listener returned boolean <code>true</code> in response to the
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_STARTED} drag event. This action type is not
|
||
|
sent if the user releases the drag shadow on a View whose listener is not registered,
|
||
|
or if the user releases the drag shadow on anything that is not part of the current
|
||
|
layout.
|
||
|
<p>
|
||
|
The listener is expected to return boolean <code>true</code> if it successfully
|
||
|
processes the drop. Otherwise, it should return <code>false</code>.
|
||
|
</p>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_ENDED}</td>
|
||
|
<td>
|
||
|
A View object's drag event listener receives this event action type
|
||
|
when the system is ending the drag operation. This action type is not necessarily
|
||
|
preceded by an {@link android.view.DragEvent#ACTION_DROP} event. If the system sent
|
||
|
a {@link android.view.DragEvent#ACTION_DROP}, receiving the
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENDED} action type does not imply that the
|
||
|
drop operation succeeded. The listener must call
|
||
|
{@link android.view.DragEvent#getResult()} to get the value that was
|
||
|
returned in response to {@link android.view.DragEvent#ACTION_DROP}. If an
|
||
|
{@link android.view.DragEvent#ACTION_DROP} event was not sent, then
|
||
|
{@link android.view.DragEvent#getResult()} returns <code>false</code>.
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p class="table-caption" id="table2">
|
||
|
<strong>Table 2.</strong> Valid DragEvent data by action type</p>
|
||
|
<table>
|
||
|
<tr>
|
||
|
<th scope="col">{@link android.view.DragEvent#getAction()} value</th>
|
||
|
<th scope="col">{@link android.view.DragEvent#getClipDescription()} value</th>
|
||
|
<th scope="col">{@link android.view.DragEvent#getLocalState()} value</th>
|
||
|
<th scope="col">{@link android.view.DragEvent#getX()} value</th>
|
||
|
<th scope="col">{@link android.view.DragEvent#getY()} value</th>
|
||
|
<th scope="col">{@link android.view.DragEvent#getClipData()} value</th>
|
||
|
<th scope="col">{@link android.view.DragEvent#getResult()} value</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_STARTED}</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_ENTERED}</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_LOCATION}</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_EXITED}</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DROP}</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>{@link android.view.DragEvent#ACTION_DRAG_ENDED}</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;"> </td>
|
||
|
<td style="text-align: center;">X</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p>
|
||
|
The {@link android.view.DragEvent#getAction()},
|
||
|
{@link android.view.DragEvent#describeContents()},
|
||
|
{@link android.view.DragEvent#writeToParcel(Parcel,int) writeToParcel()}, and
|
||
|
{@link android.view.DragEvent#toString()} methods always return valid data.
|
||
|
</p>
|
||
|
<p>
|
||
|
If a method does not contain valid data for a particular action type, it returns either
|
||
|
<code>null</code> or 0, depending on its result type.
|
||
|
</p>
|
||
|
<h3 id="AboutDragShadowBuilder">
|
||
|
The drag shadow
|
||
|
</h3>
|
||
|
<p>
|
||
|
During a drag and drop operation, the system displays a image that the user drags.
|
||
|
For data movement, this image represents the data being dragged. For other operations, the
|
||
|
image represents some aspect of the drag operation.
|
||
|
</p>
|
||
|
<p>
|
||
|
The image is called a drag shadow. You create it with methods you declare for a
|
||
|
{@link android.view.View.DragShadowBuilder} object, and then pass it to the system when you
|
||
|
start a drag using
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}.
|
||
|
As part of its response to
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()},
|
||
|
the system invokes the callback methods you've defined in
|
||
|
{@link android.view.View.DragShadowBuilder} to obtain a drag shadow.
|
||
|
</p>
|
||
|
<p>
|
||
|
The {@link android.view.View.DragShadowBuilder} class has two constructors:
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt>{@link android.view.View.DragShadowBuilder#View.DragShadowBuilder(View)}</dt>
|
||
|
<dd>
|
||
|
This constructor accepts any of your application's
|
||
|
{@link android.view.View} objects. The constructor stores the View object
|
||
|
in the {@link android.view.View.DragShadowBuilder} object, so during
|
||
|
the callback you can access it as you construct your drag shadow.
|
||
|
It doesn't have to be associated with the View (if any) that the user
|
||
|
selected to start the drag operation.
|
||
|
<p>
|
||
|
If you use this constructor, you don't have to extend
|
||
|
{@link android.view.View.DragShadowBuilder} or override its methods. By default,
|
||
|
you will get a drag shadow that has the same appearance as the View you pass as an
|
||
|
argument, centered under the location where the user is touching the screen.
|
||
|
</p>
|
||
|
</dd>
|
||
|
<dt>{@link android.view.View.DragShadowBuilder#View.DragShadowBuilder()}</dt>
|
||
|
<dd>
|
||
|
If you use this constructor, no View object is available in the
|
||
|
{@link android.view.View.DragShadowBuilder} object (the field is set to <code>null</code>).
|
||
|
If you use this constructor, and you don't extend
|
||
|
{@link android.view.View.DragShadowBuilder} or override its methods,
|
||
|
you will get an invisible drag shadow.
|
||
|
The system does <em>not</em> give an error.
|
||
|
</dd>
|
||
|
</dl>
|
||
|
<p>
|
||
|
The {@link android.view.View.DragShadowBuilder} class has two methods:
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt>
|
||
|
{@link android.view.View.DragShadowBuilder#onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()}
|
||
|
</dt>
|
||
|
<dd>
|
||
|
The system calls this method immediately after you call
|
||
|
{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}. Use it
|
||
|
to send to the system the dimensions and touch point of the drag shadow. The method has two
|
||
|
arguments:
|
||
|
<dl>
|
||
|
<dt><em>dimensions</em></dt>
|
||
|
<dd>
|
||
|
A {@link android.graphics.Point} object. The drag shadow width goes in
|
||
|
{@link android.graphics.Point#x} and its height goes in
|
||
|
{@link android.graphics.Point#y}.
|
||
|
</dd>
|
||
|
<dt><em>touch_point</em></dt>
|
||
|
<dd>
|
||
|
A {@link android.graphics.Point} object. The touch point is the location within the
|
||
|
drag shadow that should be under the user's finger during the drag. Its X
|
||
|
position goes in {@link android.graphics.Point#x} and its Y position goes in
|
||
|
{@link android.graphics.Point#y}
|
||
|
</dd>
|
||
|
</dl>
|
||
|
</dd>
|
||
|
<dt>
|
||
|
{@link android.view.View.DragShadowBuilder#onDrawShadow(Canvas) onDrawShadow()}
|
||
|
</dt>
|
||
|
<dd>
|
||
|
Immediately after the call to
|
||
|
{@link android.view.View.DragShadowBuilder#onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()}
|
||
|
the system calls
|
||
|
{@link android.view.View.DragShadowBuilder#onDrawShadow(Canvas) onDrawShadow()} to get the
|
||
|
drag shadow itself. The method has a single argument, a {@link android.graphics.Canvas}
|
||
|
object that the system constructs from the parameters you provide in
|
||
|
{@link android.view.View.DragShadowBuilder#onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()}
|
||
|
Use it to draw the drag shadow in the provided {@link android.graphics.Canvas} object.
|
||
|
</dd>
|
||
|
</dl>
|
||
|
<p>
|
||
|
To improve performance, you should keep the size of the drag shadow small. For a single item,
|
||
|
you may want to use a icon. For a multiple selection, you may want to use icons in a stack
|
||
|
rather than full images spread out over the screen.
|
||
|
</p>
|
||
|
<h2 id="DesignDragOperation">Designing a Drag and Drop Operation</h2>
|
||
|
<p>
|
||
|
This section shows step-by-step how to start a drag, how to respond to events during
|
||
|
the drag, how respond to a drop event, and how to end the drag and drop operation.
|
||
|
</p>
|
||
|
<h3 id="StartDrag">Starting a drag</h3>
|
||
|
<p>
|
||
|
The user starts a drag with a drag gesture, usually a long press, on a View object.
|
||
|
In response, you should do the following:
|
||
|
</p>
|
||
|
<ol>
|
||
|
<li>
|
||
|
As necessary, create a {@link android.content.ClipData} and
|
||
|
{@link android.content.ClipData.Item} for the data being moved. As part of the
|
||
|
ClipData object, supply metadata that is stored in a {@link android.content.ClipDescription}
|
||
|
object within the ClipData. For a drag and drop operation that does not represent data
|
||
|
movement, you may want to use <code>null</code> instead of an actual object.
|
||
|
<p>
|
||
|
For example, this code snippet shows how to respond to a long press on a ImageView
|
||
|
by creating a ClipData object that contains the tag or label of an
|
||
|
ImageView. Following this snippet, the next snippet shows how to override the methods in
|
||
|
{@link android.view.View.DragShadowBuilder}:
|
||
|
</p>
|
||
|
<pre>
|
||
|
// Create a string for the ImageView label
|
||
|
private static final String IMAGEVIEW_TAG = "icon bitmap"
|
||
|
|
||
|
// Creates a new ImageView
|
||
|
ImageView imageView = new ImageView(this);
|
||
|
|
||
|
// Sets the bitmap for the ImageView from an icon bit map (defined elsewhere)
|
||
|
imageView.setImageBitmap(mIconBitmap);
|
||
|
|
||
|
// Sets the tag
|
||
|
imageView.setTag(IMAGEVIEW_TAG);
|
||
|
|
||
|
...
|
||
|
|
||
|
// Sets a long click listener for the ImageView using an anonymous listener object that
|
||
|
// implements the OnLongClickListener interface
|
||
|
imageView.setOnLongClickListener(new View.OnLongClickListener() {
|
||
|
|
||
|
// Defines the one method for the interface, which is called when the View is long-clicked
|
||
|
public boolean onLongClick(View v) {
|
||
|
|
||
|
// Create a new ClipData.
|
||
|
// This is done in two steps to provide clarity. The convenience method
|
||
|
// ClipData.newPlainText() can create a plain text ClipData in one step.
|
||
|
|
||
|
// Create a new ClipData.Item from the ImageView object's tag
|
||
|
ClipData.Item item = new ClipData.Item(v.getTag());
|
||
|
|
||
|
// Create a new ClipData using the tag as a label, the plain text MIME type, and
|
||
|
// the already-created item. This will create a new ClipDescription object within the
|
||
|
// ClipData, and set its MIME type entry to "text/plain"
|
||
|
ClipData dragData = new ClipData(v.getTag(),ClipData.MIMETYPE_TEXT_PLAIN,item);
|
||
|
|
||
|
// Instantiates the drag shadow builder.
|
||
|
View.DrawShadowBuilder myShadow = new MyDragShadowBuilder(imageView);
|
||
|
|
||
|
// Starts the drag
|
||
|
|
||
|
v.startDrag(dragData, // the data to be dragged
|
||
|
myShadow, // the drag shadow builder
|
||
|
null, // no need to use local data
|
||
|
0 // flags (not currently used, set to 0)
|
||
|
);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
</pre>
|
||
|
</li>
|
||
|
<li>
|
||
|
The following code snippet defines {@code myDragShadowBuilder}
|
||
|
It creates a drag shadow for dragging a TextView as a small gray rectangle:
|
||
|
<pre>
|
||
|
private static class MyDragShadowBuilder extends View.DragShadowBuilder {
|
||
|
|
||
|
// The drag shadow image, defined as a drawable thing
|
||
|
private static Drawable shadow;
|
||
|
|
||
|
// Defines the constructor for myDragShadowBuilder
|
||
|
public MyDragShadowBuilder(View v) {
|
||
|
|
||
|
// Stores the View parameter passed to myDragShadowBuilder.
|
||
|
super(v);
|
||
|
|
||
|
// Creates a draggable image that will fill the Canvas provided by the system.
|
||
|
shadow = new ColorDrawable(Color.LTGRAY);
|
||
|
}
|
||
|
|
||
|
// Defines a callback that sends the drag shadow dimensions and touch point back to the
|
||
|
// system.
|
||
|
@Override
|
||
|
public void onProvideShadowMetrics (Point size, Point touch)
|
||
|
// Defines local variables
|
||
|
private int width, height;
|
||
|
|
||
|
// Sets the width of the shadow to half the width of the original View
|
||
|
width = getView().getWidth() / 2;
|
||
|
|
||
|
// Sets the height of the shadow to half the height of the original View
|
||
|
height = getView().getHeight() / 2;
|
||
|
|
||
|
// The drag shadow is a ColorDrawable. This sets its dimensions to be the same as the
|
||
|
// Canvas that the system will provide. As a result, the drag shadow will fill the
|
||
|
// Canvas.
|
||
|
shadow.setBounds(0, 0, width, height);
|
||
|
|
||
|
// Sets the size parameter's width and height values. These get back to the system
|
||
|
// through the size parameter.
|
||
|
size.set(width, height);
|
||
|
|
||
|
// Sets the touch point's position to be in the middle of the drag shadow
|
||
|
touch.set(width / 2, height / 2);
|
||
|
}
|
||
|
|
||
|
// Defines a callback that draws the drag shadow in a Canvas that the system constructs
|
||
|
// from the dimensions passed in onProvideShadowMetrics().
|
||
|
@Override
|
||
|
public void onDrawShadow(Canvas canvas) {
|
||
|
|
||
|
// Draws the ColorDrawable in the Canvas passed in from the system.
|
||
|
shadow.draw(canvas);
|
||
|
}
|
||
|
}
|
||
|
</pre>
|
||
|
<p class="note">
|
||
|
<strong>Note:</strong> Remember that you don't have to extend
|
||
|
{@link android.view.View.DragShadowBuilder}. The constructor
|
||
|
{@link android.view.View.DragShadowBuilder#View.DragShadowBuilder(View)} creates a
|
||
|
default drag shadow that's the same size as the View argument passed to it, with the
|
||
|
touch point centered in the drag shadow.
|
||
|
</p>
|
||
|
</li>
|
||
|
</ol>
|
||
|
<h3 id="HandleStart">Responding to a drag start</h3>
|
||
|
<p>
|
||
|
During the drag operation, the system dispatches drag events to the drag event listeners
|
||
|
of the View objects in the current layout. The listeners should react
|
||
|
by calling {@link android.view.DragEvent#getAction()} to get the action type.
|
||
|
At the start of a drag, this methods returns {@link android.view.DragEvent#ACTION_DRAG_STARTED}.
|
||
|
</p>
|
||
|
<p>
|
||
|
In response to an event with the action type {@link android.view.DragEvent#ACTION_DRAG_STARTED},
|
||
|
a listener should do the following:
|
||
|
</p>
|
||
|
<ol>
|
||
|
<li>
|
||
|
Call {@link android.view.DragEvent#getClipDescription()} to get the
|
||
|
{@link android.content.ClipDescription}. Use the MIME type methods in
|
||
|
{@link android.content.ClipDescription} to see if the listener can accept the data being
|
||
|
dragged.
|
||
|
<p>
|
||
|
If the drag and drop operation does not represent data movement, this may not be
|
||
|
necessary.
|
||
|
</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
If the listener can accept a drop, it should return <code>true</code>. This tells
|
||
|
the system to continue to send drag events to the listener.
|
||
|
If it can't accept a drop, it should return <code>false</code>, and the system
|
||
|
will stop sending drag events until it sends out
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENDED}.
|
||
|
</li>
|
||
|
</ol>
|
||
|
<p>
|
||
|
Note that for an {@link android.view.DragEvent#ACTION_DRAG_STARTED} event, these
|
||
|
the following {@link android.view.DragEvent} methods are not valid:
|
||
|
{@link android.view.DragEvent#getClipData()}, {@link android.view.DragEvent#getX()},
|
||
|
{@link android.view.DragEvent#getY()}, and {@link android.view.DragEvent#getResult()}.
|
||
|
</p>
|
||
|
<h3 id="HandleDuring">Handling events during the drag</h3>
|
||
|
<p>
|
||
|
During the drag, listeners that returned <code>true</code> in response to
|
||
|
the {@link android.view.DragEvent#ACTION_DRAG_STARTED} drag event continue to receive drag
|
||
|
events. The types of drag events a listener receives during the drag depend on the location of
|
||
|
the drag shadow and the visibility of the listener's View.
|
||
|
</p>
|
||
|
<p>
|
||
|
During the drag, listeners primarily use drag events to decide if they should change the
|
||
|
appearance of their View.
|
||
|
</p>
|
||
|
<p>
|
||
|
During the drag, {@link android.view.DragEvent#getAction()} returns one of three
|
||
|
values:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENTERED}:
|
||
|
The listener receives this when the touch point
|
||
|
(the point on the screen underneath the user's finger) has entered the bounding box of the
|
||
|
listener's View.
|
||
|
</li>
|
||
|
<li>
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_LOCATION}: Once the listener receives an
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENTERED} event, and before it receives an
|
||
|
A{@link android.view.DragEvent#ACTION_DRAG_EXITED} event, it receives a new
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_LOCATION} event every time the touch point moves.
|
||
|
The {@link android.view.DragEvent#getX()} and {@link android.view.DragEvent#getY()} methods
|
||
|
return the the X and Y coordinates of the touch point.
|
||
|
</li>
|
||
|
<li>
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_EXITED}: This event is sent to a listener that
|
||
|
previously received {@link android.view.DragEvent#ACTION_DRAG_ENTERED}, after
|
||
|
the drag shadow is no longer within the bounding box of the listener's View.
|
||
|
</li>
|
||
|
</ul>
|
||
|
<p>
|
||
|
The listener does not need to react to any of these action types. If the listener returns a
|
||
|
value to the system, it is ignored. Here are some guidelines for responding to each of
|
||
|
these action types:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
In response to {@link android.view.DragEvent#ACTION_DRAG_ENTERED} or
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_LOCATION}, the listener can change the appearance
|
||
|
of the View to indicate that it is about to receive a drop.
|
||
|
</li>
|
||
|
<li>
|
||
|
An event with the action type {@link android.view.DragEvent#ACTION_DRAG_LOCATION} contains
|
||
|
valid data for {@link android.view.DragEvent#getX()} and
|
||
|
{@link android.view.DragEvent#getY()}, corresponding to the location of the touch point.
|
||
|
The listener may want to use this information to alter the appearance of that part of the
|
||
|
View that is at the touch point. The listener can also use this information
|
||
|
to determine the exact position where the user is going to drop the drag shadow.
|
||
|
</li>
|
||
|
<li>
|
||
|
In response to {@link android.view.DragEvent#ACTION_DRAG_EXITED}, the listener should reset
|
||
|
any appearance changes it applied in response to
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENTERED} or
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_LOCATION}. This indicates to the user that
|
||
|
the View is no longer an imminent drop target.
|
||
|
</li>
|
||
|
</ul>
|
||
|
<h3 id="HandleDrop">Responding to a drop</h3>
|
||
|
<p>
|
||
|
When the user releases the drag shadow on a View in the application, and that View previously
|
||
|
reported that it could accept the content being dragged, the system dispatches a drag event
|
||
|
to that View with the action type {@link android.view.DragEvent#ACTION_DROP}. The listener
|
||
|
should do the following:
|
||
|
</p>
|
||
|
<ol>
|
||
|
<li>
|
||
|
Call {@link android.view.DragEvent#getClipData()} to get the
|
||
|
{@link android.content.ClipData} object that was originally supplied in the call
|
||
|
to
|
||
|
{@link android.view.View#startDrag(ClipData, View.DragShadowBuilder, Object, int) startDrag()}
|
||
|
and store it. If the drag and drop operation does not represent data movement,
|
||
|
this may not be necessary.
|
||
|
</li>
|
||
|
<li>
|
||
|
Return boolean <code>true</code> to indicate that the drop was processed successfully, or
|
||
|
boolean <code>false</code> if it was not. The returned value becomes the value returned by
|
||
|
{@link android.view.DragEvent#getResult()} for an
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENDED} event.
|
||
|
<p>
|
||
|
Note that if the system does not send out an {@link android.view.DragEvent#ACTION_DROP}
|
||
|
event, the value of {@link android.view.DragEvent#getResult()} for an
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENDED} event is <code>false</code>.
|
||
|
</p>
|
||
|
</li>
|
||
|
</ol>
|
||
|
<p>
|
||
|
For an {@link android.view.DragEvent#ACTION_DROP} event,
|
||
|
{@link android.view.DragEvent#getX()} and {@link android.view.DragEvent#getY()}
|
||
|
return the X and Y position of the drag point at the moment of the drop, using the coordinate
|
||
|
system of the View that received the drop.
|
||
|
</p>
|
||
|
<p>
|
||
|
The system does allow the user to release the drag shadow on a View whose listener is not
|
||
|
receiving drag events. It will also allow the user to release the drag shadow
|
||
|
on empty regions of the application's UI, or on areas outside of your application.
|
||
|
In all of these cases, the system does not send an event with action type
|
||
|
{@link android.view.DragEvent#ACTION_DROP}, although it does send out an
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENDED} event.
|
||
|
</p>
|
||
|
<h3 id="HandleEnd">Responding to a drag end</h3>
|
||
|
<p>
|
||
|
Immediately after the user releases the drag shadow, the system sends a
|
||
|
drag event to all of the drag event listeners in your application, with an action type of
|
||
|
{@link android.view.DragEvent#ACTION_DRAG_ENDED}. This indicates that the drag operation is
|
||
|
over.
|
||
|
</p>
|
||
|
<p>
|
||
|
Each listener should do the following:
|
||
|
</p>
|
||
|
<ol>
|
||
|
<li>
|
||
|
If listener changed its View object's appearance during the operation, it should reset the
|
||
|
View to its default appearance. This is a visual indication to the user that the operation
|
||
|
is over.
|
||
|
</li>
|
||
|
<li>
|
||
|
The listener can optionally call {@link android.view.DragEvent#getResult()} to find out more
|
||
|
about the operation. If a listener returned <code>true</code> in response to an event of
|
||
|
action type {@link android.view.DragEvent#ACTION_DROP}, then
|
||
|
{@link android.view.DragEvent#getResult()} will return boolean <code>true</code>. In all
|
||
|
other cases, {@link android.view.DragEvent#getResult()} returns boolean <code>false</code>,
|
||
|
including any case in which the system did not send out a
|
||
|
{@link android.view.DragEvent#ACTION_DROP} event.
|
||
|
</li>
|
||
|
<li>
|
||
|
The listener should return boolean <code>true</code> to the system.
|
||
|
</li>
|
||
|
</ol>
|
||
|
<p>
|
||
|
</p>
|
||
|
<h3 id="RespondEventSample">Responding to drag events: an example</h3>
|
||
|
<p>
|
||
|
All drag events are initially received by your drag event method or listener. The following
|
||
|
code snippet is a simple example of reacting to drag events in a listener:
|
||
|
</p>
|
||
|
<pre>
|
||
|
// Creates a new drag event listener
|
||
|
mDragListen = new myDragEventListener();
|
||
|
|
||
|
View imageView = new ImageView(this);
|
||
|
|
||
|
// Sets the drag event listener for the View
|
||
|
imageView.setOnDragListener(mDragListen);
|
||
|
|
||
|
...
|
||
|
|
||
|
protected class myDragEventListener implements View.OnDragEventListener {
|
||
|
|
||
|
// This is the method that the system calls when it dispatches a drag event to the
|
||
|
// listener.
|
||
|
public boolean onDrag(View v, DragEvent event) {
|
||
|
|
||
|
// Defines a variable to store the action type for the incoming event
|
||
|
final int action = event.getAction();
|
||
|
|
||
|
// Handles each of the expected events
|
||
|
switch(action) {
|
||
|
|
||
|
case DragEvent.ACTION_DRAG_STARTED:
|
||
|
|
||
|
// Determines if this View can accept the dragged data
|
||
|
if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
|
||
|
|
||
|
// As an example of what your application might do,
|
||
|
// applies a blue color tint to the View to indicate that it can accept
|
||
|
// data.
|
||
|
v.setColorFilter(Color.BLUE);
|
||
|
|
||
|
// Invalidate the view to force a redraw in the new tint
|
||
|
v.invalidate();
|
||
|
|
||
|
// returns true to indicate that the View can accept the dragged data.
|
||
|
return(true);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
// Returns false. During the current drag and drop operation, this View will
|
||
|
// not receive events again until ACTION_DRAG_ENDED is sent.
|
||
|
return(false);
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case DragEvent.ACTION_DRAG_ENTERED: {
|
||
|
|
||
|
// Applies a green tint to the View. Return true; the return value is ignored.
|
||
|
|
||
|
v.setColorFilter(Color.GREEN);
|
||
|
|
||
|
// Invalidate the view to force a redraw in the new tint
|
||
|
v.invalidate();
|
||
|
|
||
|
return(true);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case DragEvent.ACTION_DRAG_LOCATION:
|
||
|
|
||
|
// Ignore the event
|
||
|
return(true);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case DragEvent.ACTION_DRAG_EXITED:
|
||
|
|
||
|
// Re-sets the color tint to blue. Returns true; the return value is ignored.
|
||
|
v.setColorFilter(Color.BLUE);
|
||
|
|
||
|
// Invalidate the view to force a redraw in the new tint
|
||
|
v.invalidate();
|
||
|
|
||
|
return(true);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case DragEvent.ACTION_DROP:
|
||
|
|
||
|
// Gets the item containing the dragged data
|
||
|
ClipData.Item item = event.getClipData().getItemAt(0);
|
||
|
|
||
|
// Gets the text data from the item.
|
||
|
dragData = item.getText();
|
||
|
|
||
|
// Displays a message containing the dragged data.
|
||
|
Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG);
|
||
|
|
||
|
// Turns off any color tints
|
||
|
v.clearColorFilter();
|
||
|
|
||
|
// Invalidates the view to force a redraw
|
||
|
v.invalidate();
|
||
|
|
||
|
// Returns true. DragEvent.getResult() will return true.
|
||
|
return(true);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case DragEvent.ACTION_DRAG_ENDED:
|
||
|
|
||
|
// Turns off any color tinting
|
||
|
v.clearColorFilter();
|
||
|
|
||
|
// Invalidates the view to force a redraw
|
||
|
v.invalidate();
|
||
|
|
||
|
// Does a getResult(), and displays what happened.
|
||
|
if (event.getResult()) {
|
||
|
Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG);
|
||
|
|
||
|
} else {
|
||
|
Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG);
|
||
|
|
||
|
};
|
||
|
|
||
|
// returns true; the value is ignored.
|
||
|
return(true);
|
||
|
|
||
|
break;
|
||
|
|
||
|
// An unknown action type was received.
|
||
|
default:
|
||
|
Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
|
||
|
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
</pre>
|