Home | History | Annotate | Download | only in ui
      1 page.title=Drag and Drop
      2 page.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">
     98 DragAndDropDemo.java</a> and
     99                 <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DraggableDot.html">
    100 DraggableDot.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
    577 private static final String IMAGEVIEW_TAG = &quot;icon bitmap&quot;
    578 
    579 // Creates a new ImageView
    580 ImageView imageView = new ImageView(this);
    581 
    582 // Sets the bitmap for the ImageView from an icon bit map (defined elsewhere)
    583 imageView.setImageBitmap(mIconBitmap);
    584 
    585 // Sets the tag
    586 imageView.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
    592 imageView.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
    867 mDragListen = new myDragEventListener();
    868 
    869 View imageView = new ImageView(this);
    870 
    871 // Sets the drag event listener for the View
    872 imageView.setOnDragListener(mDragListen);
    873 
    874 ...
    875 
    876 protected 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