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