Vista rápida
- Permite que tus usuarios muevan datos dentro de tu diseño de actividad mediante gestos gráficos.
- Es compatible con operaciones que van más allá del movimiento de datos.
- Solo funciona dentro de una aplicación.
- Requiere API 11.
En este documento:
Clases fundamentales
Ejemplos relacionados
Consulta también:
Con el framework de arrastrar y soltar de Android, puedes permitir que tus usuarios muevan datos de un objeto View a otro del diseño actual mediante un gesto gráfico de arrastrar y soltar. El framework incluye una clase de eventos de arrastre, receptores de arrastre, y clases y métodos de ayuda.
Si bien el framework está principalmente diseñado para el movimiento de datos, puedes usarlo para otras acciones de la IU. Por ejemplo, podrías crear una app que combine colores cuando el usuario arrastre un ícono de color sobre otro ícono. No obstante, en el resto del tema se describe el framework con respecto al movimiento de datos.
Información general
Una operación de arrastrar y soltar comienza cuando el usuario hace algún gesto que reconoces como
señal para iniciar el arrastre de datos. En respuesta a esto, tu aplicación indica al sistema que el arrastre está
comenzando. El sistema vuelve a llamar a tu aplicación a fin de obtener una representación de los datos
que se arrastran. A medida que el dedo del usuario mueve esta representación (una “sombra de arrastre”)
sobre el diseño actual, el sistema envía eventos de arrastre a los objetos de receptores de eventos de arrastre y
a los métodos de callback de eventos de arrastre asociados a los objetos View del diseño.
Una vez que el usuario libera la sombra de arrastre, el sistema finaliza la operación de arrastre.
Debes crear un objeto de receptor de eventos de arrastre (“receptores”) a partir de una clase que implementa
View.OnDragListener. Debes definir el objeto de receptor de eventos de arrastre para un objeto View
con el método
setOnDragListener() del objeto View.
Cada objeto View también tiene un método de callback
onDragEvent(). Estos dos elementos se describen con más detalle en la sección
El receptor de eventos de arrastre y el método de callback.
Nota: Por razones de simplicidad, en las siguientes secciones, se hace referencia a la rutina que recibe los eventos de arrastre como “receptor de eventos de arrastre”, aunque en realidad pueda tratarse de un método de callback.
Cuando inicias un arrastre, debes incluir los datos que mueves y los metadatos que describen estos datos como parte de la llamada al sistema. Durante el arrastre, el sistema envía eventos de arrastre a los receptores de eventos de arrastre o métodos de callback de cada objeto View del diseño. Los receptores o métodos de callback pueden usar los metadatos para determinar si aceptan o no los datos cuando se sueltan. Si el usuario suelta los datos mediante un objeto View, y el receptor o método de callback del objeto View indica previamente al sistema que aceptará la acción de soltar, el sistema envía los datos al receptor o método de callback en un evento de arrastre.
Tu aplicación llama al método
startDrag()
para indicar al sistema que inicie un evento de arrastre. Esto notifica al sistema que comience a enviar eventos de arrastre. El método también envía los datos que
arrastras.
Puedes llamar a
startDrag()
para acceder a cualquier objeto View adjunto del diseño actual. El sistema solo usa el objeto View para obtener acceso
a la configuración global de tu diseño.
Una vez que tu aplicación llama a
startDrag(),
en el resto del proceso se usan eventos que el sistema envía a los objetos View de tu diseño
actual.
El proceso de arrastrar y soltar
Básicamente, existen cuatro pasos o estados en el proceso de arrastrar y soltar:
- Servicio iniciado
-
En respuesta al gesto de inicio de arrastre del usuario, tu aplicación llama a
startDrag()para indicar al sistema que inicie un arrastre. Los argumentosstartDrag()proporcionan los datos que se arrastrarán, los metadatos de estos y un callback para dibujar la sombra de arrastre.En primer lugar, el sistema responde mediante un llamado a tu aplicación para obtener una sombra de arrastre. Luego, muestra la sombra de arrastre en el dispositivo.
A continuación, envía un evento de arrastre con el tipo de acción
ACTION_DRAG_STARTEDa los receptores del evento de arrastre de todos los objetos View del diseño actual. Para continuar recibiendo eventos de arrastre, incluido un posible evento de acción de soltar, un receptor de eventos de arrastre debe mostrartrue. Esto registra el receptor en el sistema. Solo los receptores registrados continúan recibiendo eventos de arrastre. En este punto, los receptores también pueden cambiar la apariencia de su objeto View a fin de mostrar que el receptor puede aceptar un evento de acción de soltar.Si el receptor de eventos de arrastre muestra
false, no recibirá eventos de arrastre para la operación actual hasta que el sistema envíe un evento de arrastre con el tipo de acciónACTION_DRAG_ENDED. Al enviarfalse, el receptor indica al sistema que no está interesado en la operación de arrastre y que no aceptará los datos arrastrados. - Servicio continuado
-
El usuario continúa el arrastre. A medida que la sombra de arrastre intersecta el cuadro de límite de un objeto View,
el sistema envía uno o más eventos de arrastre al receptor de eventos de arrastre del objeto
View (si dicho receptor se encuentra registrado para recibir eventos). El receptor puede decidir
modificar la apariencia su objeto View en respuesta al evento. Por ejemplo, si el evento
indica que la sombra de arrastre ingresó en el cuadro de límite del objeto View
(tipo de acción
ACTION_DRAG_ENTERED), el receptor puede destacar su vista en respuesta a esto. - Servicio soltado
-
El usuario suelta la sombra de arrastre dentro del cuadro de límite de un objeto View que puede aceptar los
datos. El sistema envía al receptor del objeto View un evento de arrastre con el tipo de acción
ACTION_DROP. El evento de arrastre contiene los datos que se pasaron al sistema en la llamada astartDrag()que dio inicio a la operación. Se espera que el receptor muestre un booleanotrueal sistema si el código para aceptar el arrastre tiene éxito.Ten en cuenta que este paso solo se realiza si el usuario suelta la sombra de arrastre dentro del cuadro de límite de un objeto View cuyo receptor se encuentre registrado para recibir eventos de arrastre. Si el usuario suelta la sombra de arrastre en otra situación, no se envían eventos de arrastre
ACTION_DROP. - Servicio finalizado
-
Después de que el usuario suelta la sombra de arrastre y el sistema envía (si es necesario)
un evento de arrastre con el tipo de acción
ACTION_DROP, el sistema envía un evento de arrastre con el tipo de acciónACTION_DRAG_ENDEDpara indicar que la operación de arrastre ha finalizado. Esto se realiza independientemente del lugar en el cual el usuario haya liberado la sombra de arrastre. El evento se envía a todos los receptores que se encuentran registrados para recibir eventos de arrastre, incluso si estos receptores han recibido el eventoACTION_DROP.
Cada uno de estos cuatro pasos se describe con más detalle en la sección Diseño de una operación de arrastrar y soltar.
El receptor de eventos de arrastre y el método de callback
Un objeto View recibe eventos de arrastre con un receptor de eventos de arrastre que implementa
View.OnDragListener o con su
método de callback onDragEvent(DragEvent).
Cuando el sistema llama al método o al receptor, les pasa
un objeto DragEvent.
Probablemente te convenga usar el receptor en la mayoría de los casos. Cuando diseñas IU, por lo general,
no creas una subclase de las clases de elementos View; más bien, el uso del método de callback te obliga a hacerlo a fin de
anular el método. De manera comparativa, puedes implementar una clase de receptor y después usarlo con
diferentes objetos View. También puedes implementarlo como clase integrada anónima. Para
definir el receptor de un objeto View, llama a
setOnDragListener().
Puedes tener un receptor y un método de callback para el objeto View. Si esto sucede,
el sistema primero llama al receptor. El sistema no llama al método de callback a menos que el
receptor muestre false.
La combinación del método onDragEvent(DragEvent) y el
View.OnDragListener equivale a la combinación
del onTouchEvent() y el
View.OnTouchListener usados con eventos táctiles.
Eventos de arrastre
El sistema envía un evento de arrastre en forma de un objeto DragEvent. El
objeto contiene un tipo de acción que informa al receptor lo que sucede en el proceso de
arrastrar y soltar. El objeto incluye otros datos, según el tipo de acción.
Para obtener el tipo de acción, un receptor llama a getAction(). Existen
seis valores posibles, definidos por constantes en la clase DragEvent. Estos
se enumeran en la tabla 1.
El objeto DragEvent también contiene los datos que tu aplicación proporcionó
al sistema en la llamada a
startDrag().
Parte de los datos son válidos solamente para determinados tipos de acción. Los datos válidos para cada
tipo de acción se resumen en la tabla 2. También se describen en detalle con
el evento para el cual son válidos en la sección
Diseño de una operación de arrastrar y soltar.
Tabla 1: Tipos de acciones DragEvent.
| Valor getAction() | Significado |
|---|---|
ACTION_DRAG_STARTED |
Un receptor de eventos de arrastre de un objeto View recibe este tipo de acción de eventos inmediatamente después de que la
aplicación llama a
startDrag() y
obtiene una sombra de arrastre.
|
ACTION_DRAG_ENTERED |
Un receptor de eventos de arrastre de un objeto View recibe este tipo de acción de eventos cuando la sombra de arrastre
ingresa en el cuadro de límite del objeto View. Este es el primer tipo de acción de evento que
recibe el receptor cuando la sombra de arrastre ingresa en el cuadro de límite. Si el receptor desea
continuar recibiendo eventos de arrastre para esta operación, debe mostrar un booleano
true al sistema.
|
ACTION_DRAG_LOCATION |
Un receptor de eventos de arrastre de un objeto View recibe este tipo de acción de eventos después de recibir un
evento ACTION_DRAG_ENTERED mientras la sombra de arrastre
todavía se encuentra dentro del cuadro de límite de la Vista.
|
ACTION_DRAG_EXITED |
Un receptor de eventos de arrastre de un objeto View recibe este tipo de acción de eventos después de recibir un evento
ACTION_DRAG_ENTERED y al menos un evento
ACTION_DRAG_LOCATION, y después de que el usuario mueve
la sombra de arrastre fuera del cuadro de límite del objeto View.
|
ACTION_DROP |
Un receptor de eventos de arrastre de un objeto View recibe este tipo de acción de eventos cuando el usuario
suelta la sombra de arrastre sobre el objeto View. Este tipo de acción solo se envía a un receptor del objeto
View si el receptor muestra un booleano true en respuesta al evento de arrastre
ACTION_DRAG_STARTED. Este tipo de acción no se
envía si el usuario suelta la sombra de arrastre sobre un objeto View cuyo receptor no se encuentre registrado
o si suelta la sombra de arrastre sobre cualquier elemento que no forme parte del diseño
actual.
Se espera que el receptor muestre un booleano |
ACTION_DRAG_ENDED |
Un receptor de eventos de arrastre de un objeto View recibe este tipo de acción de eventos
cuando el sistema finaliza la operación de arrastre. Este tipo de acción no necesariamente va
precedida por un evento ACTION_DROP. Si el sistema envía
un ACTION_DROP, la recepción del tipo de acción
ACTION_DRAG_ENDED no implica que la
operación de la acción de soltar haya tenido éxito. El receptor debe llamar a
getResult() para obtener el valor que se
mostró en respuesta a ACTION_DROP. Si no se envía un
evento ACTION_DROP,
getResult() muestra false.
|
Tabla 2: Datos de DragEvent válidos por tipo de acción.
Valor getAction() |
valor getClipDescription() |
valor getLocalState() |
valor getX() |
valor getY() |
valor getClipData() |
valor getResult() |
|---|---|---|---|---|---|---|
ACTION_DRAG_STARTED |
X | X | X | |||
ACTION_DRAG_ENTERED |
X | X | X | X | ||
ACTION_DRAG_LOCATION |
X | X | X | X | ||
ACTION_DRAG_EXITED |
X | X | ||||
ACTION_DROP |
X | X | X | X | X | |
ACTION_DRAG_ENDED |
X | X | X |
Los métodos getAction(),
describeContents(),
writeToParcel() y
toString() siempre muestran datos válidos.
Si un método no contiene datos válidos para un tipo de acción en particular, muestra
null o 0, según su tipo de resultado.
La sombra de arrastre
Durante una operación de arrastrar y soltar, el sistema muestra una imagen que arrastra el usuario. En el caso del movimiento de datos, esta imagen representa los datos que se arrastran. Para las demás operaciones, la imagen representa algún aspecto de la operación de arrastre.
La imagen se denomina “sombra de arrastre”. Se crea con métodos que se declaran para un
objeto View.DragShadowBuilder y después se pasa al sistema cuando
inicias un arrastre con
startDrag().
Como parte de su respuesta a
startDrag(),
el sistema invoca los métodos de callback definidos en
View.DragShadowBuilder a fin de obtener una sombra de arrastre.
La clase View.DragShadowBuilder tiene dos constructores:
View.DragShadowBuilder(View)-
Este constructor acepta cualquier objeto
Viewde tu aplicación. El constructor almacena el objeto View en el objetoView.DragShadowBuilder, por lo cual, durante el callback puedes acceder a él a medida que construyes tu sombra de arrastre. No tiene que estar asociado al objeto View (si existe) que el usuario seleccionó para iniciar la operación de arrastre.Si usas este constructor, no es necesario que amplíes
View.DragShadowBuildero anules sus métodos. Según la configuración predeterminada, obtendrás una sombra de arrastre con la misma apariencia que el objeto View que pasas como argumento, centrada debajo de la ubicación en la cual el usuario toca la pantalla. View.DragShadowBuilder()-
Si usas este constructor, no habrá disponibles objetos View en el objeto
View.DragShadowBuilder(el campo se define ennull). Si usas este constructor, y no amplíasView.DragShadowBuilderni anulas sus métodos, obtendrás una sombra de arrastre invisible. El sistema no muestra un error.
La clase View.DragShadowBuilder tiene dos métodos:
-
onProvideShadowMetrics() -
El sistema llama a este método inmediatamente después de que llamas a
startDrag(). Úsalo para enviar al sistema las dimensiones y el punto de contacto de la sombra de arrastre. Este método tiene dos argumentos:- dimensions
-
Objeto
Point. El ancho de la sombra de arrastre se inserta enxy su altura se coloca eny. - touch_point
-
Objeto
Point. El punto de contacto es la ubicación dentro de la sombra de arrastre que debe estar debajo del dedo del usuario durante el arrastre. Su posición X va enxy su posición Y va eny
-
onDrawShadow() -
Inmediatamente después de la llamada a
onProvideShadowMetrics(), el sistema llama aonDrawShadow()para obtener la sombra de arrastre propiamente dicha. El método tiene un argumento único, un objetoCanvasque el sistema construye a partir de los parámetros que proporcionas enonProvideShadowMetrics(). Úsalo para dibujar la sombra de arrastre en el objetoCanvasproporcionado.
A fin de mejorar el rendimiento, debes conservar un tamaño pequeño para la sombra de arrastre. En el caso de un elemento único, probablemente te convenga usar un ícono. Para una selección múltiple, se te recomienda usar íconos en una pila en lugar de imágenes completas desplegadas en la pantalla.
Diseño de una operación de arrastrar y soltar
En esta sección se muestra paso a paso la manera de iniciar un arrastre, responder a eventos durante este, responder a un evento de soltar, y finalizar la operación de arrastrar y soltar.
Inicio de un arrastre
El usuario inicia un arrastre con un gesto de arrastre; por lo general, mediante una pulsación prolongada en un objeto View. En respuesta, debes hacer lo siguiente:
-
Según sea necesario, crea un objeto
ClipDatayClipData.Itempara los datos que mueves. Como parte del objeto ClipData, suministra metadatos que se almacenen en un objetoClipDescriptiondentro de ClipData. En el caso de una operación de arrastrar y soltar que no represente movimientos de datos, es recomendable que usesnullen lugar de un objeto real.Por ejemplo, en este fragmento de código se muestra la manera de responder a una pulsación prolongada en un elemento ImageView creando un objeto ClipData que contiene la etiqueta de un elemento ImageView. Después de este fragmento, el fragmento siguiente muestra la manera de anular los métodos en
View.DragShadowBuilder:// Create a string for the ImageView label private static final String IMAGEVIEW_TAG = "icon bitmap" // Creates a new ImageView ImageView imageView = new ImageView(this); // Sets the bitmap for the ImageView from an icon bit map (defined elsewhere) imageView.setImageBitmap(mIconBitmap); // Sets the tag imageView.setTag(IMAGEVIEW_TAG); ... // Sets a long click listener for the ImageView using an anonymous listener object that // implements the OnLongClickListener interface imageView.setOnLongClickListener(new View.OnLongClickListener() { // Defines the one method for the interface, which is called when the View is long-clicked public boolean onLongClick(View v) { // Create a new ClipData. // This is done in two steps to provide clarity. The convenience method // ClipData.newPlainText() can create a plain text ClipData in one step. // Create a new ClipData.Item from the ImageView object's tag ClipData.Item item = new ClipData.Item(v.getTag()); // Create a new ClipData using the tag as a label, the plain text MIME type, and // the already-created item. This will create a new ClipDescription object within the // ClipData, and set its MIME type entry to "text/plain" ClipData dragData = new ClipData(v.getTag(),ClipData.MIMETYPE_TEXT_PLAIN,item); // Instantiates the drag shadow builder. View.DragShadowBuilder myShadow = new MyDragShadowBuilder(imageView); // Starts the drag v.startDrag(dragData, // the data to be dragged myShadow, // the drag shadow builder null, // no need to use local data 0 // flags (not currently used, set to 0) ); } } -
El siguiente fragmento de código define
myDragShadowBuilder. Crea una sombra de arrastre para arrastrar un elemento TextView como un pequeño rectángulo gris:private static class MyDragShadowBuilder extends View.DragShadowBuilder { // The drag shadow image, defined as a drawable thing private static Drawable shadow; // Defines the constructor for myDragShadowBuilder public MyDragShadowBuilder(View v) { // Stores the View parameter passed to myDragShadowBuilder. super(v); // Creates a draggable image that will fill the Canvas provided by the system. shadow = new ColorDrawable(Color.LTGRAY); } // Defines a callback that sends the drag shadow dimensions and touch point back to the // system. @Override public void onProvideShadowMetrics (Point size, Point touch) { // Defines local variables private int width, height; // Sets the width of the shadow to half the width of the original View width = getView().getWidth() / 2; // Sets the height of the shadow to half the height of the original View height = getView().getHeight() / 2; // The drag shadow is a ColorDrawable. This sets its dimensions to be the same as the // Canvas that the system will provide. As a result, the drag shadow will fill the // Canvas. shadow.setBounds(0, 0, width, height); // Sets the size parameter's width and height values. These get back to the system // through the size parameter. size.set(width, height); // Sets the touch point's position to be in the middle of the drag shadow touch.set(width / 2, height / 2); } // Defines a callback that draws the drag shadow in a Canvas that the system constructs // from the dimensions passed in onProvideShadowMetrics(). @Override public void onDrawShadow(Canvas canvas) { // Draws the ColorDrawable in the Canvas passed in from the system. shadow.draw(canvas); } }Nota: Recuerda que no es necesario que amplíes
View.DragShadowBuilder. El constructorView.DragShadowBuilder(View)crea una sombra de arrastre predeterminada del mismo tamaño que el argumento View que se pasó, con el punto de contacto centrado en la sombra de arrastre.
Respuesta a un inicio de arrastre
Durante la operación de arrastre, el sistema envía eventos de arrastre a los receptores de eventos de arrastre
de los objetos View del diseño actual. Los receptores deben responder
llamando a getAction() para obtener el tipo de acción.
Al inicio del arrastre, este método muestra ACTION_DRAG_STARTED.
En respuesta a un evento con el tipo de acción ACTION_DRAG_STARTED,
un receptor debe hacer lo siguiente:
-
Llamar a
getClipDescription()para obtener laClipDescription. Usar los métodos de tipo de MIME enClipDescriptiona fin de ver si el receptor puede aceptar los datos que se arrastran.Si la operación de arrastrar y soltar no representa ningún movimiento de datos, es posible que esta acción no sea necesaria.
-
Si el receptor puede aceptar una acción de soltar, se debe mostrar
true. Esto indica al sistema que continúe enviando eventos de arrastre al receptor. Si el receptor no puede aceptar una acción de soltar, debe mostrarfalsey el sistema detendrá el envío de eventos de arrastre hasta que se envíeACTION_DRAG_ENDED.
Ten en cuenta que en el caso de un evento ACTION_DRAG_STARTED, los
siguientes métodosDragEvent no son válidos:
getClipData(), getX(),
getY() y getResult().
Control de eventos durante el arrastre
Durante el arrastre, los receptores que muestran true en respuesta al
evento de arrastre ACTION_DRAG_STARTED continúan recibiendo eventos de
arrastre. Los tipos de eventos de arrastre que recibe un receptor durante el arrastre dependen de la ubicación
de la sombra de arrastre y la visibilidad del objeto View del receptor.
Durante el arrastre, los receptores usan principalmente eventos de arrastre para determinar si deben cambiar la apariencia de su objeto View.
Durante el arrastre, getAction() muestra uno de estos tres
valores:
-
ACTION_DRAG_ENTERED: el receptor recibe esto cuando el punto de contacto (punto de la pantalla que se encuentra debajo del dedo del usuario) ingresa en el cuadro de límite del objeto View del receptor. -
ACTION_DRAG_LOCATION: una vez que el receptor recibe un eventoACTION_DRAG_ENTERED, y antes de que reciba un eventoACTION_DRAG_EXITED, recibe un nuevo eventoACTION_DRAG_LOCATIONcada vez que el punto de contacto se mueve. Los métodosgetX()ygetY()muestran las coordenadas X e Y del punto de contacto. -
ACTION_DRAG_EXITED: este evento se envía a un receptor que anteriormente recibeACTION_DRAG_ENTERED, una vez que la sombra de arrastre deja estar dentro del cuadro de límite del objeto View del receptor.
No es necesario que el receptor responda a ninguno de estos tipos de acción. Si el receptor muestra un valor al sistema, dicho valor se ignora. A continuación, se describen algunas pautas para responder a cada uno de estos tipos de acción:
-
En respuesta a
ACTION_DRAG_ENTEREDoACTION_DRAG_LOCATION, el receptor puede cambiar la apariencia del objeto View a fin de indicar que está a punto de recibir una acción de soltar. -
Un evento con el tipo de acción
ACTION_DRAG_LOCATIONcontiene datos válidos paragetX()ygetY(), que corresponden a la ubicación del punto de contacto. El receptor podrá usar esta información para modificar la apariencia de esa parte del objeto View que se encuentre en el punto de contacto. El receptor también puede usar esta información para determinar la ubicación exacta en la cual el usuario soltará la sombra de arrastre. -
En respuesta a
ACTION_DRAG_EXITED, el receptor debe restablecer todo cambio en la apariencia que se haya aplicado en respuesta aACTION_DRAG_ENTEREDoACTION_DRAG_LOCATION. Esto indica al usuario que el objeto View ya no es un destino inminente de la acción de soltar.
Respuesta a una acción de soltar
Cuando el usuario suelta la sombra de arrastre en un objeto View de la aplicación, y este informa
anteriormente que puede aceptar el contenido arrastrado, el sistema envía el evento de arrastre
a ese objeto View con el tipo de acción ACTION_DROP. El receptor
debe hacer lo siguiente:
-
Llamar a
getClipData()para obtener el objetoClipDatasuministrado originalmente en la llamada astartDrag()y almacenarlo. Si la operación de arrastrar y soltar no representa ningún movimiento de datos, es posible que esta acción no sea necesaria. -
Mostrar un booleano
truepara indicar que la acción de soltar se procesó con éxito o mostrar el booleanofalsesi esto no sucedió. El valor mostrado se convierte en el valor que muestragetResult()para un eventoACTION_DRAG_ENDED.Ten en cuenta que, si el sistema no envía un evento
ACTION_DROP, el valor degetResult()para un eventoACTION_DRAG_ENDEDesfalse.
En el caso de un evento ACTION_DROP,
getX() y getY()
muestran la ubicación de X e Y del punto de arrastre al momento de la acción de soltar, mediante el sistema de
coordenadas del objeto View que recibió la acción de soltar.
El sistema no permite que el usuario suelte la sombra de arrastre de un objeto View cuyo receptor no
reciba eventos de arrastre. También permitirá al usuario soltar la sombra de arrastre
en regiones vacías de la IU de la aplicación o en áreas fuera de tu aplicación.
En todos estos casos, el sistema no envía un evento con el tipo de acción
ACTION_DROP, aunque sí envía un evento
ACTION_DRAG_ENDED.
Respuesta a una finalización de arrastre
Inmediatamente después de que el usuario suelta la sombra de arrastre, el sistema envía un
evento de arrastre a todos los receptores de eventos de arrastre de tu aplicación, con un tipo de acción
ACTION_DRAG_ENDED. Esto indica que la operación de arrastre
ha finalizado.
Cada receptor debe hacer lo siguiente:
- Si el receptor cambió la apariencia de su objeto View durante la operación, deberá restablecer la apariencia predeterminada del objeto View. Se trata de una indicación visual que indica al usuario que la operación ha finalizado.
-
Opcionalmente, el receptor puede llamar a
getResult()a fin de obtener más información sobre la operación. Si un receptor mostrótrueen respuesta a un evento de tipo de acciónACTION_DROP,getResult()mostrará un booleanotrue. En todos los demás casos,getResult()muestra el booleanofalse, incluido cualquier caso en el cual el sistema no haya enviado un eventoACTION_DROP. -
El receptor debe mostrar al sistema el booleano
true.
Respuesta a eventos de arrastre: ejemplo
Inicialmente, tu receptor o tu método de eventos de arrastre reciben todos los eventos de arrastre. El siguiente fragmento de código es un ejemplo simple de una respuesta a eventos de arrastre en un receptor:
// Creates a new drag event listener
mDragListen = new myDragEventListener();
View imageView = new ImageView(this);
// Sets the drag event listener for the View
imageView.setOnDragListener(mDragListen);
...
protected class myDragEventListener implements View.OnDragListener {
// This is the method that the system calls when it dispatches a drag event to the
// listener.
public boolean onDrag(View v, DragEvent event) {
// Defines a variable to store the action type for the incoming event
final int action = event.getAction();
// Handles each of the expected events
switch(action) {
case DragEvent.ACTION_DRAG_STARTED:
// Determines if this View can accept the dragged data
if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
// As an example of what your application might do,
// applies a blue color tint to the View to indicate that it can accept
// data.
v.setColorFilter(Color.BLUE);
// Invalidate the view to force a redraw in the new tint
v.invalidate();
// returns true to indicate that the View can accept the dragged data.
return true;
}
// Returns false. During the current drag and drop operation, this View will
// not receive events again until ACTION_DRAG_ENDED is sent.
return false;
case DragEvent.ACTION_DRAG_ENTERED:
// Applies a green tint to the View. Return true; the return value is ignored.
v.setColorFilter(Color.GREEN);
// Invalidate the view to force a redraw in the new tint
v.invalidate();
return true;
case DragEvent.ACTION_DRAG_LOCATION:
// Ignore the event
return true;
case DragEvent.ACTION_DRAG_EXITED:
// Re-sets the color tint to blue. Returns true; the return value is ignored.
v.setColorFilter(Color.BLUE);
// Invalidate the view to force a redraw in the new tint
v.invalidate();
return true;
case DragEvent.ACTION_DROP:
// Gets the item containing the dragged data
ClipData.Item item = event.getClipData().getItemAt(0);
// Gets the text data from the item.
dragData = item.getText();
// Displays a message containing the dragged data.
Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG);
// Turns off any color tints
v.clearColorFilter();
// Invalidates the view to force a redraw
v.invalidate();
// Returns true. DragEvent.getResult() will return true.
return true;
case DragEvent.ACTION_DRAG_ENDED:
// Turns off any color tinting
v.clearColorFilter();
// Invalidates the view to force a redraw
v.invalidate();
// Does a getResult(), and displays what happened.
if (event.getResult()) {
Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG);
} else {
Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG);
}
// returns true; the value is ignored.
return true;
// An unknown action type was received.
default:
Log.e("DragDrop Example","Unknown action type received by OnDragListener.");
break;
}
return false;
}
};