1page.title=Drag and Drop
2page.tags=clipdata,dragevent,onlongclicklistener
3@jd:body
4
5<div id="qv-wrapper">
6    <div id="qv">
7        <h2>Quickview</h2>
8            <ul>
9                <li>
10                    Allow users to move data within your Activity layout using graphical gestures.
11                </li>
12                <li>
13                    Supports operations besides data movement.
14                </li>
15                <li>
16                    Only works within a single application.
17                </li>
18                <li>
19                    Requires API 11.
20                </li>
21            </ul>
22        <h2>In this document</h2>
23        <ol>
24            <li>
25                <a href="#AboutDragging">Overview</a>
26                <ol>
27                    <li>
28                        <a href="#DragDropLifecycle">The drag/drop process</a>
29                    </li>
30                    <li>
31                        <a href="#AboutDragListeners">The drag event listener and callback method</a>
32                    </li>
33                    <li>
34                        <a href="#AboutDragEvent">Drag events</a>
35                    </li>
36                    <li>
37                        <a href="#AboutDragShadowBuilder">
38                        The drag shadow</a>
39                    </li>
40                </ol>
41            </li>
42            <li>
43                <a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>
44                <ol>
45                    <li>
46                        <a href="#StartDrag">Starting a drag</a>
47                    </li>
48                    <li>
49                        <a href="#HandleStart">Responding to a drag start</a>
50                    </li>
51                    <li>
52                        <a href="#HandleDuring">Handling events during the drag</a>
53                    </li>
54                    <li>
55                        <a href="#HandleDrop">Responding to a drop</a>
56                    </li>
57                    <li>
58                        <a href="#HandleEnd">Responding to a drag end</a>
59                    </li>
60                    <li>
61                        <a href="#RespondEventSample">Responding to drag events: an example</a>
62                    </li>
63                </ol>
64            </li>
65        </ol>
66        <h2>Key classes</h2>
67        <ol>
68            <li>
69                {@link android.view.View View}
70            </li>
71            <li>
72                {@link android.view.View.OnLongClickListener OnLongClickListener}
73            </li>
74            <li>
75                {@link android.view.View.OnDragListener OnDragListener}
76            </li>
77            <li>
78                {@link android.view.DragEvent DragEvent}
79            </li>
80            <li>
81                {@link android.view.View.DragShadowBuilder DragShadowBuilder}
82            </li>
83            <li>
84                {@link android.content.ClipData ClipData}
85            </li>
86            <li>
87                {@link android.content.ClipDescription ClipDescription}
88            </li>
89        </ol>
90        <h2>Related Samples</h2>
91        <ol>
92            <li>
93                <a href="{@docRoot}resources/samples/HoneycombGallery/index.html">
94                Honeycomb Gallery</a>.
95            </li>
96            <li>
97                <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.html">
98DragAndDropDemo.java</a> and
99                <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DraggableDot.html">
100DraggableDot.java</a> in <a href="{@docRoot}resources/samples/ApiDemos/index.html">Api Demos</a>.
101            </li>
102        </ol>
103        <h2>See also</h2>
104        <ol>
105            <li>
106            <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
107            </li>
108            <li>
109                <a href="{@docRoot}guide/topics/ui/ui-events.html">Input Events</a>
110            </li>
111        </ol>
112    </div>
113</div>
114<p>
115    With the Android drag/drop framework, you can allow your users to move data
116    from one View to another View in the current layout using a graphical drag and drop gesture.
117    The framework includes a drag event class, drag listeners, and helper methods and classes.
118</p>
119<p>
120    Although the framework is primarily designed for data movement, you can use
121    it for other UI actions. For example, you could create an app that mixes colors when the user
122    drags a color icon over another icon. The rest of this topic, however, describes the
123    framework in terms of data movement.
124</p>
125<h2 id="AboutDragging">Overview</h2>
126<p>
127    A drag and drop operation starts when the user makes some gesture that you recognize as a
128    signal to start dragging data. In response, your application tells the system that the drag is
129    starting. The system calls back to your application to get a representation of the data
130    being dragged. As the user's finger moves this representation (a &quot;drag shadow&quot;)
131    over the current layout, the system sends drag events to the drag event listener objects and
132    drag event callback methods associated with the {@link android.view.View} objects in the layout.
133    Once the user releases the drag shadow, the system ends the drag operation.
134</p>
135<p>
136    You create a drag event listener object (&quot;listeners&quot;) from a class that implements
137    {@link android.view.View.OnDragListener}. You set the drag event listener object for a View
138    with the View object's
139    {@link android.view.View#setOnDragListener(View.OnDragListener) setOnDragListener()} method.
140    Each View object also has a {@link android.view.View#onDragEvent(DragEvent) onDragEvent()}
141    callback method. Both of these are described in more detail in the section
142    <a href="#AboutDragListeners">The drag event listener and callback method</a>.
143</p>
144<p class="note">
145    <strong>Note</strong>: For the sake of simplicity, the following sections refer to the routine
146    that receives drag events as the &quot;drag event listener&quot;, even though it may actually
147    be a callback method.
148</p>
149<p>
150    When you start a drag, you include both the data you are moving and metadata describing this
151    data as part of the call to the system. During the drag, the system sends drag events to the
152    drag event listeners or callback methods of each View in the layout. The listeners or callback
153    methods can use the metadata to decide if they want to accept the data when it is dropped.
154    If the user drops the data over a View object, and that View object's listener or callback
155    method has previously told the system that it wants to accept the drop, then the system sends
156    the data to the listener or callback method in a drag event.
157</p>
158<p>
159    Your application tells the system to start a drag by calling the
160    {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
161    method. This tells the system to start sending drag events. The method also sends the data that
162    you are dragging.
163</p>
164<p>
165    You can call
166    {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
167    for any attached View in the current layout. The system only uses the View object to get access
168    to global settings in your layout.
169</p>
170<p>
171    Once your application calls
172    {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()},
173    the rest of the process uses events that the system sends to the View objects in your current
174    layout.
175</p>
176<h3 id="DragDropLifecycle">The drag/drop process</h3>
177<p>
178    There are basically four steps or states in the drag and drop process:
179</p>
180<dl>
181    <dt>
182        <em>Started</em>
183    </dt>
184    <dd>
185        In response to the user's gesture to begin a drag, your application calls
186        {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
187        to tell the system to start a drag. The arguments
188        {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
189        provide the data to be dragged, metadata for this data, and a callback for drawing the
190        drag shadow.
191        <p>
192            The system first responds by calling back to your application to get a drag shadow. It
193            then displays the drag shadow on the device.
194        </p>
195        <p>
196            Next, the system sends a drag event with action type
197            {@link android.view.DragEvent#ACTION_DRAG_STARTED} to the drag event listeners for
198            all the View objects in the current layout. To continue to receive drag events,
199            including a possible drop event, a drag event listener must return <code>true</code>.
200            This registers the listener with the system. Only registered listeners continue to
201            receive drag events. At this point, listeners can also change the appearance of their
202            View object to show that the listener can accept a drop event.
203        </p>
204        <p>
205            If the drag event listener returns <code>false</code>, then it will not receive drag
206            events for the current operation until the system sends a drag event with action type
207            {@link android.view.DragEvent#ACTION_DRAG_ENDED}. By sending <code>false</code>, the
208            listener tells the system that it is not interested in the drag operation and
209            does not want to accept the dragged data.
210        </p>
211    </dd>
212    <dt>
213        <em>Continuing</em>
214    </dt>
215    <dd>
216        The user continues the drag. As the drag shadow intersects the bounding box of a View
217        object, the system sends one or more drag events to the View object's drag event
218        listener (if it is registered to receive events). The listener may choose to
219        alter its View object's appearance in response to the event. For example, if the event
220        indicates that the drag shadow has entered the bounding box of the View
221        (action type {@link android.view.DragEvent#ACTION_DRAG_ENTERED}), the listener
222        can react by highlighting its View.
223    </dd>
224    <dt>
225        <em>Dropped</em>
226    </dt>
227    <dd>
228        The user releases the drag shadow within the bounding box of a View that can accept the
229        data. The system sends the View object's listener a drag event with action type
230        {@link android.view.DragEvent#ACTION_DROP}. The drag event contains the data that was
231        passed to the system in the call to
232        {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}
233        that started the operation. The listener is expected to return boolean <code>true</code> to
234        the system if code for accepting the drop succeeds.
235        <p>
236            Note that this step only occurs if the user drops the drag shadow within the bounding
237            box of a View whose listener is registered to receive drag events. If the user releases
238            the drag shadow in any other situation, no {@link android.view.DragEvent#ACTION_DROP}
239            drag event is sent.
240        </p>
241    </dd>
242    <dt>
243        <em>Ended</em>
244    </dt>
245    <dd>
246        After the user releases the drag shadow, and after the system sends out (if necessary)
247        a drag event with action type {@link android.view.DragEvent#ACTION_DROP}, the system sends
248        out a drag event with action type {@link android.view.DragEvent#ACTION_DRAG_ENDED} to
249        indicate that the drag operation is over. This is done regardless of where the user released
250        the drag shadow. The event is sent to every listener that is registered to receive drag
251        events, even if the listener received the {@link android.view.DragEvent#ACTION_DROP} event.
252    </dd>
253</dl>
254<p>
255    Each of these four steps is described in more detail in the section
256    <a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>.
257</p>
258<h3 id="AboutDragListeners">The drag event listener and callback method</h3>
259<p>
260    A View receives drag events with either a drag event listener that implements
261    {@link android.view.View.OnDragListener} or with its
262    {@link android.view.View#onDragEvent(DragEvent)} callback method.
263    When the system calls the method or listener, it passes to them
264    a {@link android.view.DragEvent} object.
265</p>
266<p>
267    You will probably want to use the listener in most cases. When you design UIs, you usually
268    don't subclass View classes, but using the callback method forces you to do this in order to
269    override the method. In comparison, you can implement one listener class and then use it with
270    several different View objects. You can also implement it as an anonymous inline class. To
271    set the listener for a View object, call
272{@link android.view.View#setOnDragListener(android.view.View.OnDragListener) setOnDragListener()}.
273</p>
274<p>
275    You can have both a listener and a callback method for View object. If this occurs,
276    the system first calls the listener. The system doesn't call the callback method unless the
277    listener returns <code>false</code>.
278</p>
279<p>
280    The combination of the {@link android.view.View#onDragEvent(DragEvent)} method and
281    {@link android.view.View.OnDragListener} is analogous to the combination
282    of the {@link android.view.View#onTouchEvent(MotionEvent) onTouchEvent()} and
283    {@link android.view.View.OnTouchListener} used with touch events.
284</p>
285<h3 id="AboutDragEvent">Drag events</h3>
286<p>
287    The system sends out a drag event in the form of a {@link android.view.DragEvent} object. The
288    object contains an action type that tells the listener what is happening in the drag/drop
289    process. The object contains other data, depending on the action type.
290</p>
291<p>
292    To get the action type, a listener calls {@link android.view.DragEvent#getAction()}. There
293    are six possible values, defined by constants in the {@link android.view.DragEvent} class. These
294    are listed in <a href="#table1">table 1</a>.
295</p>
296<p>
297    The {@link android.view.DragEvent} object also contains the data that your application provided
298    to the system in the call to
299    {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}.
300    Some of the data is valid only for certain action types. The data that is valid for each action
301    type is summarized in <a href="#table2">table 2</a>. It is also described in detail with
302    the event for which it is valid in the section
303    <a href="#DesignDragOperation">Designing a Drag and Drop Operation</a>.
304</p>
305<p class="table-caption" id="table1">
306  <strong>Table 1.</strong> DragEvent action types
307</p>
308<table>
309    <tr>
310        <th scope="col">getAction() value</th>
311        <th scope="col">Meaning</th>
312    </tr>
313    <tr>
314        <td>{@link android.view.DragEvent#ACTION_DRAG_STARTED}</td>
315        <td>
316            A View object's drag event listener receives this event action type just after the
317            application calls
318{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()} and
319            gets a drag shadow.
320        </td>
321    </tr>
322    <tr>
323        <td>{@link android.view.DragEvent#ACTION_DRAG_ENTERED}</td>
324        <td>
325            A View object's drag event listener receives this event action type when the drag shadow
326            has just entered the bounding box of the View. This is the first event action type the
327            listener receives when the drag shadow enters the bounding box. If the listener wants to
328            continue receiving drag events for this operation, it must return boolean
329            <code>true</code> to the system.
330        </td>
331    </tr>
332    <tr>
333        <td>{@link android.view.DragEvent#ACTION_DRAG_LOCATION}</td>
334        <td>
335            A View object's drag event listener receives this event action type after it receives a
336            {@link android.view.DragEvent#ACTION_DRAG_ENTERED} event while the drag shadow is
337            still within the bounding box of the View.
338        </td>
339    </tr>
340    <tr>
341        <td>{@link android.view.DragEvent#ACTION_DRAG_EXITED}</td>
342        <td>
343            A View object's drag event listener receives this event action type after it receives a
344            {@link android.view.DragEvent#ACTION_DRAG_ENTERED} and at least one
345            {@link android.view.DragEvent#ACTION_DRAG_LOCATION} event, and after the user has moved
346            the drag shadow outside the bounding box of the View.
347        </td>
348    </tr>
349    <tr>
350        <td>{@link android.view.DragEvent#ACTION_DROP}</td>
351        <td>
352            A View object's drag event listener receives this event action type when the user
353            releases the drag shadow over the View object. This action type is only sent to a View
354            object's listener if the listener returned boolean <code>true</code> in response to the
355            {@link android.view.DragEvent#ACTION_DRAG_STARTED} drag event. This action type is not
356            sent if the user releases the drag shadow on a View whose listener is not registered,
357            or if the user releases the drag shadow on anything that is not part of the current
358            layout.
359            <p>
360                The listener is expected to return boolean <code>true</code> if it successfully
361                processes the drop. Otherwise, it should return <code>false</code>.
362            </p>
363        </td>
364    </tr>
365    <tr>
366        <td>{@link android.view.DragEvent#ACTION_DRAG_ENDED}</td>
367        <td>
368            A View object's drag event listener receives this event action type
369            when the system is ending the drag operation. This action type is not necessarily
370            preceded by an {@link android.view.DragEvent#ACTION_DROP} event. If the system sent
371            a {@link android.view.DragEvent#ACTION_DROP}, receiving the
372            {@link android.view.DragEvent#ACTION_DRAG_ENDED} action type does not imply that the
373            drop operation succeeded. The listener must call
374            {@link android.view.DragEvent#getResult()} to get the value that was
375            returned in response to {@link android.view.DragEvent#ACTION_DROP}. If an
376            {@link android.view.DragEvent#ACTION_DROP} event was not sent, then
377            {@link android.view.DragEvent#getResult()} returns <code>false</code>.
378        </td>
379    </tr>
380</table>
381<p class="table-caption" id="table2">
382  <strong>Table 2.</strong> Valid DragEvent data by action type</p>
383<table>
384    <tr>
385        <th scope="col">{@link android.view.DragEvent#getAction()} value</th>
386        <th scope="col">{@link android.view.DragEvent#getClipDescription()} value</th>
387        <th scope="col">{@link android.view.DragEvent#getLocalState()} value</th>
388        <th scope="col">{@link android.view.DragEvent#getX()} value</th>
389        <th scope="col">{@link android.view.DragEvent#getY()} value</th>
390        <th scope="col">{@link android.view.DragEvent#getClipData()} value</th>
391        <th scope="col">{@link android.view.DragEvent#getResult()} value</th>
392    </tr>
393    <tr>
394        <td>{@link android.view.DragEvent#ACTION_DRAG_STARTED}</td>
395        <td style="text-align: center;">X</td>
396        <td style="text-align: center;">X</td>
397        <td style="text-align: center;">X</td>
398        <td style="text-align: center;">&nbsp;</td>
399        <td style="text-align: center;">&nbsp;</td>
400        <td style="text-align: center;">&nbsp;</td>
401    </tr>
402    <tr>
403        <td>{@link android.view.DragEvent#ACTION_DRAG_ENTERED}</td>
404        <td style="text-align: center;">X</td>
405        <td style="text-align: center;">X</td>
406        <td style="text-align: center;">X</td>
407        <td style="text-align: center;">X</td>
408        <td style="text-align: center;">&nbsp;</td>
409        <td style="text-align: center;">&nbsp;</td>
410    </tr>
411    <tr>
412        <td>{@link android.view.DragEvent#ACTION_DRAG_LOCATION}</td>
413        <td style="text-align: center;">X</td>
414        <td style="text-align: center;">X</td>
415        <td style="text-align: center;">X</td>
416        <td style="text-align: center;">X</td>
417        <td style="text-align: center;">&nbsp;</td>
418        <td style="text-align: center;">&nbsp;</td>
419    </tr>
420    <tr>
421        <td>{@link android.view.DragEvent#ACTION_DRAG_EXITED}</td>
422        <td style="text-align: center;">X</td>
423        <td style="text-align: center;">X</td>
424        <td style="text-align: center;">&nbsp;</td>
425        <td style="text-align: center;">&nbsp;</td>
426        <td style="text-align: center;">&nbsp;</td>
427        <td style="text-align: center;">&nbsp;</td>
428    </tr>
429    <tr>
430        <td>{@link android.view.DragEvent#ACTION_DROP}</td>
431        <td style="text-align: center;">X</td>
432        <td style="text-align: center;">X</td>
433        <td style="text-align: center;">X</td>
434        <td style="text-align: center;">X</td>
435        <td style="text-align: center;">X</td>
436        <td style="text-align: center;">&nbsp;</td>
437    </tr>
438    <tr>
439        <td>{@link android.view.DragEvent#ACTION_DRAG_ENDED}</td>
440        <td style="text-align: center;">X</td>
441        <td style="text-align: center;">X</td>
442        <td style="text-align: center;">&nbsp;</td>
443        <td style="text-align: center;">&nbsp;</td>
444        <td style="text-align: center;">&nbsp;</td>
445        <td style="text-align: center;">X</td>
446    </tr>
447</table>
448<p>
449    The {@link android.view.DragEvent#getAction()},
450    {@link android.view.DragEvent#describeContents()},
451    {@link android.view.DragEvent#writeToParcel(Parcel,int) writeToParcel()}, and
452    {@link android.view.DragEvent#toString()} methods always return valid data.
453</p>
454<p>
455    If a method does not contain valid data for a particular action type, it returns either
456    <code>null</code> or 0, depending on its result type.
457</p>
458<h3 id="AboutDragShadowBuilder">
459    The drag shadow
460</h3>
461<p>
462    During a drag and drop operation, the system displays a image that the user drags.
463    For data movement, this image represents the data being dragged. For other operations, the
464    image represents some aspect of the drag operation.
465</p>
466<p>
467    The image is called a drag shadow. You create it with methods you declare for a
468    {@link android.view.View.DragShadowBuilder} object, and then pass it to the system when you
469    start a drag using
470    {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}.
471    As part of its response to
472    {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()},
473    the system invokes the callback methods you've defined in
474    {@link android.view.View.DragShadowBuilder} to obtain a drag shadow.
475</p>
476<p>
477    The {@link android.view.View.DragShadowBuilder} class has two constructors:
478</p>
479    <dl>
480    <dt>{@link android.view.View.DragShadowBuilder#View.DragShadowBuilder(View)}</dt>
481    <dd>
482        This constructor accepts any of your application's
483        {@link android.view.View} objects. The constructor stores the View object
484        in the {@link android.view.View.DragShadowBuilder} object, so during
485        the callback you can access it as you construct your drag shadow.
486        It doesn't have to be associated with the View (if any) that the user
487        selected to start the drag operation.
488        <p>
489            If you use this constructor, you don't have to extend
490            {@link android.view.View.DragShadowBuilder} or override its methods. By default,
491            you will get a drag shadow that has the same appearance as the View you pass as an
492            argument, centered under the location where the user is touching the screen.
493        </p>
494    </dd>
495    <dt>{@link android.view.View.DragShadowBuilder#View.DragShadowBuilder()}</dt>
496    <dd>
497        If you use this constructor, no View object is available in the
498        {@link android.view.View.DragShadowBuilder} object (the field is set to <code>null</code>).
499        If you use this constructor, and you don't extend
500        {@link android.view.View.DragShadowBuilder} or override its methods,
501        you will get an invisible drag shadow.
502        The system does <em>not</em> give an error.
503    </dd>
504</dl>
505<p>
506    The {@link android.view.View.DragShadowBuilder} class has two methods:
507</p>
508<dl>
509    <dt>
510{@link android.view.View.DragShadowBuilder#onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()}
511    </dt>
512    <dd>
513        The system calls this method immediately after you call
514{@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}. Use it
515        to send to the system the dimensions and touch point of the drag shadow. The method has two
516        arguments:
517        <dl>
518            <dt><em>dimensions</em></dt>
519            <dd>
520                A {@link android.graphics.Point} object. The drag shadow width goes in
521                {@link android.graphics.Point#x} and its height goes in
522                {@link android.graphics.Point#y}.
523            </dd>
524            <dt><em>touch_point</em></dt>
525            <dd>
526                A {@link android.graphics.Point} object. The touch point is the location within the
527                drag shadow that should be under the user's finger during the drag. Its X
528                position goes in {@link android.graphics.Point#x} and its Y position goes in
529                {@link android.graphics.Point#y}
530            </dd>
531        </dl>
532    </dd>
533    <dt>
534       {@link android.view.View.DragShadowBuilder#onDrawShadow(Canvas) onDrawShadow()}
535    </dt>
536    <dd>
537        Immediately after the call to
538{@link android.view.View.DragShadowBuilder#onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()}
539        the system calls
540        {@link android.view.View.DragShadowBuilder#onDrawShadow(Canvas) onDrawShadow()} to get the
541        drag shadow itself. The method has a single argument, a {@link android.graphics.Canvas}
542        object that the system constructs from the parameters you provide in
543{@link android.view.View.DragShadowBuilder#onProvideShadowMetrics(Point,Point) onProvideShadowMetrics()}
544        Use it to draw the drag shadow in the provided {@link android.graphics.Canvas} object.
545    </dd>
546</dl>
547<p>
548    To improve performance, you should keep the size of the drag shadow small. For a single item,
549    you may want to use a icon. For a multiple selection, you may want to use icons in a stack
550    rather than full images spread out over the screen.
551</p>
552<h2 id="DesignDragOperation">Designing a Drag and Drop Operation</h2>
553<p>
554    This section shows step-by-step how to start a drag, how to respond to events during
555    the drag, how respond to a drop event, and how to end the drag and drop operation.
556</p>
557<h3 id="StartDrag">Starting a drag</h3>
558<p>
559    The user starts a drag with a drag gesture, usually a long press, on a View object.
560    In response, you should do the following:
561</p>
562<ol>
563     <li>
564        As necessary, create a {@link android.content.ClipData} and
565        {@link android.content.ClipData.Item} for the data being moved. As part of the
566        ClipData object, supply metadata that is stored in a {@link android.content.ClipDescription}
567        object within the ClipData. For a drag and drop operation that does not represent data
568        movement, you may want to use <code>null</code> instead of an actual object.
569        <p>
570            For example, this code snippet shows how to respond to a long press on a ImageView
571            by creating a ClipData object that contains the tag or label of an
572            ImageView. Following this snippet, the next snippet shows how to override the methods in
573            {@link android.view.View.DragShadowBuilder}:
574        </p>
575<pre>
576// Create a string for the ImageView label
577private static final String IMAGEVIEW_TAG = &quot;icon bitmap&quot;
578
579// Creates a new ImageView
580ImageView imageView = new ImageView(this);
581
582// Sets the bitmap for the ImageView from an icon bit map (defined elsewhere)
583imageView.setImageBitmap(mIconBitmap);
584
585// Sets the tag
586imageView.setTag(IMAGEVIEW_TAG);
587
588    ...
589
590// Sets a long click listener for the ImageView using an anonymous listener object that
591// implements the OnLongClickListener interface
592imageView.setOnLongClickListener(new View.OnLongClickListener() {
593
594    // Defines the one method for the interface, which is called when the View is long-clicked
595    public boolean onLongClick(View v) {
596
597    // Create a new ClipData.
598    // This is done in two steps to provide clarity. The convenience method
599    // ClipData.newPlainText() can create a plain text ClipData in one step.
600
601    // Create a new ClipData.Item from the ImageView object's tag
602    ClipData.Item item = new ClipData.Item(v.getTag());
603
604    // Create a new ClipData using the tag as a label, the plain text MIME type, and
605    // the already-created item. This will create a new ClipDescription object within the
606    // ClipData, and set its MIME type entry to &quot;text/plain&quot;
607    ClipData dragData = new ClipData(v.getTag(),ClipData.MIMETYPE_TEXT_PLAIN,item);
608
609    // Instantiates the drag shadow builder.
610    View.DragShadowBuilder myShadow = new MyDragShadowBuilder(imageView);
611
612    // Starts the drag
613
614            v.startDrag(dragData,  // the data to be dragged
615                        myShadow,  // the drag shadow builder
616                        null,      // no need to use local data
617                        0          // flags (not currently used, set to 0)
618            );
619
620    }
621}
622</pre>
623    </li>
624    <li>
625        The following code snippet defines {@code myDragShadowBuilder}
626        It creates a drag shadow for dragging a TextView as a small gray rectangle:
627<pre>
628    private static class MyDragShadowBuilder extends View.DragShadowBuilder {
629
630    // The drag shadow image, defined as a drawable thing
631    private static Drawable shadow;
632
633        // Defines the constructor for myDragShadowBuilder
634        public MyDragShadowBuilder(View v) {
635
636            // Stores the View parameter passed to myDragShadowBuilder.
637            super(v);
638
639            // Creates a draggable image that will fill the Canvas provided by the system.
640            shadow = new ColorDrawable(Color.LTGRAY);
641        }
642
643        // Defines a callback that sends the drag shadow dimensions and touch point back to the
644        // system.
645        &#64;Override
646        public void onProvideShadowMetrics (Point size, Point touch)
647            // Defines local variables
648            private int width, height;
649
650            // Sets the width of the shadow to half the width of the original View
651            width = getView().getWidth() / 2;
652
653            // Sets the height of the shadow to half the height of the original View
654            height = getView().getHeight() / 2;
655
656            // The drag shadow is a ColorDrawable. This sets its dimensions to be the same as the
657            // Canvas that the system will provide. As a result, the drag shadow will fill the
658            // Canvas.
659            shadow.setBounds(0, 0, width, height);
660
661            // Sets the size parameter's width and height values. These get back to the system
662            // through the size parameter.
663            size.set(width, height);
664
665            // Sets the touch point's position to be in the middle of the drag shadow
666            touch.set(width / 2, height / 2);
667        }
668
669        // Defines a callback that draws the drag shadow in a Canvas that the system constructs
670        // from the dimensions passed in onProvideShadowMetrics().
671        &#64;Override
672        public void onDrawShadow(Canvas canvas) {
673
674            // Draws the ColorDrawable in the Canvas passed in from the system.
675            shadow.draw(canvas);
676        }
677    }
678</pre>
679        <p class="note">
680            <strong>Note:</strong> Remember that you don't have to extend
681            {@link android.view.View.DragShadowBuilder}. The constructor
682            {@link android.view.View.DragShadowBuilder#View.DragShadowBuilder(View)} creates a
683            default drag shadow that's the same size as the View argument passed to it, with the
684            touch point centered in the drag shadow.
685        </p>
686    </li>
687</ol>
688<h3 id="HandleStart">Responding to a drag start</h3>
689<p>
690    During the drag operation, the system dispatches drag events to the drag event listeners
691    of the View objects in the current layout. The listeners should react
692    by calling {@link android.view.DragEvent#getAction()} to get the action type.
693    At the start of a drag, this methods returns {@link android.view.DragEvent#ACTION_DRAG_STARTED}.
694</p>
695<p>
696    In response to an event with the action type {@link android.view.DragEvent#ACTION_DRAG_STARTED},
697    a listener should do the following:
698</p>
699<ol>
700    <li>
701        Call {@link android.view.DragEvent#getClipDescription()} to get the
702        {@link android.content.ClipDescription}. Use the MIME type methods in
703        {@link android.content.ClipDescription} to see if the listener can accept the data being
704        dragged.
705        <p>
706            If the drag and drop operation does not represent data movement, this may not be
707            necessary.
708        </p>
709    </li>
710    <li>
711        If the listener can accept a drop, it should return <code>true</code>. This tells
712        the system to continue to send drag events to the listener.
713        If it can't accept a drop, it should return <code>false</code>, and the system
714        will stop sending drag events until it sends out
715        {@link android.view.DragEvent#ACTION_DRAG_ENDED}.
716    </li>
717</ol>
718<p>
719    Note that for an {@link android.view.DragEvent#ACTION_DRAG_STARTED} event, these
720    the following {@link android.view.DragEvent} methods are not valid:
721    {@link android.view.DragEvent#getClipData()}, {@link android.view.DragEvent#getX()},
722    {@link android.view.DragEvent#getY()}, and {@link android.view.DragEvent#getResult()}.
723</p>
724<h3 id="HandleDuring">Handling events during the drag</h3>
725<p>
726    During the drag, listeners that returned <code>true</code> in response to
727    the {@link android.view.DragEvent#ACTION_DRAG_STARTED} drag event continue to receive drag
728    events. The types of drag events a listener receives during the drag depend on the location of
729    the drag shadow and the visibility of the listener's View.
730</p>
731<p>
732    During the drag, listeners primarily use drag events to decide if they should change the
733    appearance of their View.
734</p>
735<p>
736    During the drag, {@link android.view.DragEvent#getAction()} returns one of three
737    values:
738</p>
739<ul>
740    <li>
741        {@link android.view.DragEvent#ACTION_DRAG_ENTERED}:
742        The listener receives this when the touch point
743        (the point on the screen underneath the user's finger) has entered the bounding box of the
744        listener's View.
745    </li>
746    <li>
747        {@link android.view.DragEvent#ACTION_DRAG_LOCATION}: Once the listener receives an
748        {@link android.view.DragEvent#ACTION_DRAG_ENTERED} event, and before it receives an
749        A{@link android.view.DragEvent#ACTION_DRAG_EXITED} event, it receives a new
750        {@link android.view.DragEvent#ACTION_DRAG_LOCATION} event every time the touch point moves.
751        The {@link android.view.DragEvent#getX()} and {@link android.view.DragEvent#getY()} methods
752        return the X and Y coordinates of the touch point.
753    </li>
754    <li>
755        {@link android.view.DragEvent#ACTION_DRAG_EXITED}:  This event is sent to a listener that
756        previously received {@link android.view.DragEvent#ACTION_DRAG_ENTERED}, after
757        the drag shadow is no longer within the bounding box of the listener's View.
758    </li>
759</ul>
760<p>
761    The listener does not need to react to any of these action types. If the listener returns a
762    value to the system, it is ignored. Here are some guidelines for responding to each of
763    these action types:
764</p>
765<ul>
766    <li>
767        In response to {@link android.view.DragEvent#ACTION_DRAG_ENTERED} or
768        {@link android.view.DragEvent#ACTION_DRAG_LOCATION}, the listener can change the appearance
769        of the View to indicate that it is about to receive a drop.
770    </li>
771    <li>
772        An event with the action type {@link android.view.DragEvent#ACTION_DRAG_LOCATION} contains
773        valid data for {@link android.view.DragEvent#getX()} and
774        {@link android.view.DragEvent#getY()}, corresponding to the location of the touch point.
775        The listener may want to use this information to alter the appearance of that part of the
776        View that is at the touch point. The listener can also use this information
777        to determine the exact position where the user is going to drop the drag shadow.
778    </li>
779    <li>
780        In response to {@link android.view.DragEvent#ACTION_DRAG_EXITED}, the listener should reset
781        any appearance changes it applied in response to
782        {@link android.view.DragEvent#ACTION_DRAG_ENTERED} or
783        {@link android.view.DragEvent#ACTION_DRAG_LOCATION}. This indicates to the user that
784        the View is no longer an imminent drop target.
785    </li>
786</ul>
787<h3 id="HandleDrop">Responding to a drop</h3>
788<p>
789    When the user releases the drag shadow on a View in the application, and that View previously
790    reported that it could accept the content being dragged, the system dispatches a drag event
791    to that View with the action type {@link android.view.DragEvent#ACTION_DROP}. The listener
792    should do the following:
793</p>
794<ol>
795    <li>
796        Call {@link android.view.DragEvent#getClipData()} to get the
797        {@link android.content.ClipData} object that was originally supplied in the call
798        to
799{@link android.view.View#startDrag(ClipData, View.DragShadowBuilder, Object, int) startDrag()}
800        and store it. If the drag and drop operation does not represent data movement,
801        this may not be necessary.
802    </li>
803    <li>
804        Return boolean <code>true</code> to indicate that the drop was processed successfully, or
805        boolean <code>false</code> if it was not. The returned value becomes the value returned by
806        {@link android.view.DragEvent#getResult()} for an
807        {@link android.view.DragEvent#ACTION_DRAG_ENDED} event.
808        <p>
809            Note that if the system does not send out an {@link android.view.DragEvent#ACTION_DROP}
810            event, the value of {@link android.view.DragEvent#getResult()} for an
811            {@link android.view.DragEvent#ACTION_DRAG_ENDED} event is <code>false</code>.
812        </p>
813    </li>
814</ol>
815<p>
816    For an {@link android.view.DragEvent#ACTION_DROP} event,
817    {@link android.view.DragEvent#getX()} and {@link android.view.DragEvent#getY()}
818    return the X and Y position of the drag point at the moment of the drop, using the coordinate
819    system of the View that received the drop.
820</p>
821<p>
822    The system does allow the user to release the drag shadow on a View whose listener is not
823    receiving drag events. It will also allow the user to release the drag shadow
824    on empty regions of the application's UI, or on areas outside of your application.
825    In all of these cases, the system does not send an event with action type
826    {@link android.view.DragEvent#ACTION_DROP}, although it does send out an
827    {@link android.view.DragEvent#ACTION_DRAG_ENDED} event.
828</p>
829<h3 id="HandleEnd">Responding to a drag end</h3>
830<p>
831    Immediately after the user releases the drag shadow, the system sends a
832    drag event to all of the drag event listeners in your application, with an action type of
833    {@link android.view.DragEvent#ACTION_DRAG_ENDED}. This indicates that the drag operation is
834    over.
835</p>
836<p>
837    Each listener should do the following:
838</p>
839<ol>
840    <li>
841        If listener changed its View object's appearance during the operation, it should reset the
842        View to its default appearance. This is a visual indication to the user that the operation
843        is over.
844    </li>
845    <li>
846        The listener can optionally call {@link android.view.DragEvent#getResult()} to find out more
847        about the operation. If a listener returned <code>true</code> in response to an event of
848        action type {@link android.view.DragEvent#ACTION_DROP}, then
849        {@link android.view.DragEvent#getResult()} will return boolean <code>true</code>. In all
850        other cases, {@link android.view.DragEvent#getResult()} returns boolean <code>false</code>,
851        including any case in which the system did not send out a
852        {@link android.view.DragEvent#ACTION_DROP} event.
853    </li>
854    <li>
855        The listener should return boolean <code>true</code> to the system.
856    </li>
857</ol>
858<p>
859</p>
860<h3 id="RespondEventSample">Responding to drag events: an example</h3>
861<p>
862    All drag events are initially received by your drag event method or listener. The following
863    code snippet is a simple example of reacting to drag events in a listener:
864</p>
865<pre>
866// Creates a new drag event listener
867mDragListen = new myDragEventListener();
868
869View imageView = new ImageView(this);
870
871// Sets the drag event listener for the View
872imageView.setOnDragListener(mDragListen);
873
874...
875
876protected class myDragEventListener implements View.OnDragListener {
877
878    // This is the method that the system calls when it dispatches a drag event to the
879    // listener.
880    public boolean onDrag(View v, DragEvent event) {
881
882        // Defines a variable to store the action type for the incoming event
883        final int action = event.getAction();
884
885        // Handles each of the expected events
886        switch(action) {
887
888            case DragEvent.ACTION_DRAG_STARTED:
889
890                // Determines if this View can accept the dragged data
891                if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
892
893                    // As an example of what your application might do,
894                    // applies a blue color tint to the View to indicate that it can accept
895                    // data.
896                    v.setColorFilter(Color.BLUE);
897
898                    // Invalidate the view to force a redraw in the new tint
899                    v.invalidate();
900
901                    // returns true to indicate that the View can accept the dragged data.
902                    return true;
903
904                }
905
906                // Returns false. During the current drag and drop operation, this View will
907                // not receive events again until ACTION_DRAG_ENDED is sent.
908                return false;
909
910            case DragEvent.ACTION_DRAG_ENTERED:
911
912                // Applies a green tint to the View. Return true; the return value is ignored.
913
914                v.setColorFilter(Color.GREEN);
915
916                // Invalidate the view to force a redraw in the new tint
917                v.invalidate();
918
919                return true;
920
921            case DragEvent.ACTION_DRAG_LOCATION:
922
923                // Ignore the event
924                return true;
925
926            case DragEvent.ACTION_DRAG_EXITED:
927
928                // Re-sets the color tint to blue. Returns true; the return value is ignored.
929                v.setColorFilter(Color.BLUE);
930
931                // Invalidate the view to force a redraw in the new tint
932                v.invalidate();
933
934                return true;
935
936            case DragEvent.ACTION_DROP:
937
938                // Gets the item containing the dragged data
939                ClipData.Item item = event.getClipData().getItemAt(0);
940
941                // Gets the text data from the item.
942                dragData = item.getText();
943
944                // Displays a message containing the dragged data.
945                Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG);
946
947                // Turns off any color tints
948                v.clearColorFilter();
949
950                // Invalidates the view to force a redraw
951                v.invalidate();
952
953                // Returns true. DragEvent.getResult() will return true.
954                return true;
955
956            case DragEvent.ACTION_DRAG_ENDED:
957
958                // Turns off any color tinting
959                v.clearColorFilter();
960
961                // Invalidates the view to force a redraw
962                v.invalidate();
963
964                // Does a getResult(), and displays what happened.
965                if (event.getResult()) {
966                    Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG);
967
968                } else {
969                    Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG);
970
971                }
972
973                // returns true; the value is ignored.
974                return true;
975
976            // An unknown action type was received.
977            default:
978                Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
979                break;
980        }
981        
982        return false;
983    }
984};
985</pre>
986