Visualização rápida
- Permite que os usuários movam dados dentro do layout da Activity usando gestos gráficos.
- Permite operações além da movimentação de dados.
- Funciona apenas com um único aplicativo.
- Exige a API 11.
Neste documento
Classes principais
Exemplos relacionados
Veja também
Com a estrutura de trabalho de arrastar e soltar do Android, você pode permitir que usuários movam dados de uma View para outra no layout atual usando um gesto gráfico de arrastar e soltar. A estrutura de trabalho contém uma classe de eventos de arrastar, ouvintes de arrastar e métodos e classes auxiliares.
Embora a estrutura de trabalho seja projetada principalmente para movimentação de dados, é possível usá-la para outras ações de IU. Por exemplo: você pode criar um aplicativo que mistura cores quando o usuário arrasta um ícone colorido sobre outro ícone. No entanto, o resto desse tópico descreve a estrutura de trabalho em termos de movimentação de dados.
Visão geral
Uma operação de arrastar e soltar começa quando o usuário faz um gesto reconhecido como um
sinal para começar a arrastar dados. Como resposta, o aplicativo informa ao sistema que a ação de arrastar está
começando. O sistema executa um retorno de chamada para o aplicativo para obter uma representação dos dados
sendo arrastados. Conforme o dedo do usuário move essa representação (uma “sombra da ação de arrastar”)
sobre o layout atual, o sistema envia eventos de arrastar aos objetos de ouvinte de eventos de arrastar e
aos métodos de retorno de chamada dos eventos de arrastar associados aos objetos View no layout.
Depois que o usuário liberar a sombra da ação de arrastar, o sistema encerrará a operação de arrastar.
Você cria um objeto de ouvinte de evento de arrastar (“ouvintes”) de uma classe que implemente
View.OnDragListener. O objeto ouvinte do evento de arrastar para uma View
é definido com o método
setOnDragListener() do objeto View.
Cada objeto View também tem um método de retorno de chamada onDragEvent().
Ambos estão descritos em mais detalhes na seção
O ouvinte do evento de arrastar e o método de retorno de chamada.
Observação: Para simplificar, as seções a seguir se referem à rotina que recebe eventos de arrastar como o “ouvinte de eventos de arrastar”, mesmo que ele possa ser na verdade um método de retorno de chamada.
Ao iniciar uma ação de arrastar, incluem-se os dados a mover e os metadados que descrevem esses dados como parte da chamada do sistema. Durante a ação de arrastar, o sistema envia eventos de arrastar aos ouvintes de evento de arrastar ou métodos de retorno de chamada de cada View do layout. Os ouvintes ou métodos de retorno de chamada podem usar os metadados para decidir se querem aceitar os dados quando são soltos. Se o usuário soltar os dados sobre um objeto View e o ouvinte ou método de retorno de chamada dessa View informou previamente ao sistema que quer aceitar a ação de soltar, o sistema enviará os dados ao ouvinte ou método de retorno de chamada em um evento de arrastar.
O aplicativo instrui o sistema a chamar
o método startDrag()
para iniciar uma ação de arrastar. Isso instrui o sistema a começar a enviar eventos de arrastar. O método também envia os dados
sendo arrastados.
Você pode chamar
startDrag()
para qualquer View anexada ao layout atual. O sistema usa o objeto View apenas para obter acesso
às configurações globais no layout.
Depois que o aplicativo chama
startDrag(),
o resto do processo usa eventos que o sistema envia a objetos View no layout
atual.
O processo de arrastar e soltar
Existem essencialmente quatro etapas ou estados no processo de arrastar e soltar:
- Iniciado
-
Em resposta ao gesto do usuário de iniciar uma ação de arrastar, o aplicativo chama
startDrag()para instruir o sistema a iniciar uma ação de arrastar. Os argumentosstartDrag()fornecem os dados a serem arrastados, os metadados desses dados e um retorno de chamada para desenhar a sombra da ação de arrastar.Primeiro, o sistema responde executando um retorno de chamada ao aplicativo para obter a sombra da ação de arrastar. Em seguida, ele exibe a sombra da ação de arrastar no dispositivo.
Depois, o sistema envia um evento de arrastar com tipo de ação
ACTION_DRAG_STARTEDaos ouvintes de eventos de arrastar de todos os objetos View no layout atual. Para continuar a receber eventos de arrastar, inclusive um possível evento de soltar, o ouvinte de eventos de arrastar deve retornartrue. Esse retorno registra o ouvinte no sistema. Somente ouvintes registrados continuam a receber eventos de arrastar. Nesse momento, os ouvintes também podem alterar a aparência do objeto View para mostrar que o ouvinte pode aceitar um evento de soltar.Se o ouvinte de eventos retornar
false, não receberá eventos de arrastar para a operação atual até que o sistema enviar um evento de arrastar com tipo de açãoACTION_DRAG_ENDED. Ao enviarfalse, o ouvinte informa ao sistema que não está interessado na operação de arrastar e não quer aceitar os dados arrastados. - Continuando
-
O usuário continua a ação de arrastar. Quando a sombra da ação de arrastar cruzar a caixa delimitadora de um objeto
View, o sistema enviará um ou mais eventos de arrastar ao ouvinte de eventos de arrastar do objeto
View (se ele estiver registrado para receber eventos). O ouvinte pode optar por
alterar a aparência do objeto View em resposta ao evento. Por exemplo, se o evento
indicar que a sombra da ação de arrastar entrou na caixa delimitadora da View
(tipo de ação
ACTION_DRAG_ENTERED), o ouvinte poderá reagir destacando sua View. - Solto
-
O usuário libera a sombra da ação arrastar dentro da caixa delimitadora de uma View que pode aceitar
os dados. O sistema envia ao ouvinte do objeto View um evento de arrastar com tipo de ação
ACTION_DROP. O evento de arrastar contém os dados passados ao sistema na chamada destartDrag()que iniciou a operação. O ouvinte deverá retornar umtruebooleano ao sistema se o código para aceitar a ação de soltar for bem-sucedido.Observe que essa etapa ocorre apenas quando o usuário solta a sombra da ação de arrastar dentro da caixa delimitadora de uma View cujo ouvinte está registrado para receber eventos de arrastar. Se o usuário soltar a sombra da ação de arrastar em qualquer outra situação, nenhum evento de arrastar será enviado
ACTION_DROP. - Encerrado
-
Depois que o usuário soltar a sombra da ação de arrastar e o sistema enviar (se necessário)
um evento de arrastar com o tipo de ação
ACTION_DROP, o sistema enviará um evento de arrastar com o tipo de açãoACTION_DRAG_ENDEDpara indicar o término da operação de arrastar. Isso será feito independentemente do local onde o usuário soltar a sombra da ação de arrastar. O evento é enviado a todos os ouvintes registrados para receber eventos de arrastar, mesmo se o ouvinte recebeu o eventoACTION_DROP.
Essas quatro etapas são descritas mais detalhadamente na seção Projetar uma operação de arrastar e soltar.
O ouvinte de eventos de arrastar e o método de retorno de chamada
Uma View recebe eventos de arrastar com um ouvinte de eventos de arrastar que implementa
View.OnDragListener ou com seu
método de retorno de chamada onDragEvent(DragEvent).
Quando o sistema chama o método ou ouvinte, passa-lhes
um objeto DragEvent.
Você provavelmente usará o ouvinte na maioria dos casos. Ao projetar IUs, normalmente
não são criadas subclasses das classes View, mas o uso do método de retorno de chamada exige que isso seja feito para
modificar o método. Por outro lado, é possível implementar uma classe de ouvinte e usá-la
com diversos objetos View. Também é possível implementá-la como uma classe anônima em linha. Para
definir o ouvinte de um objeto View, chame
setOnDragListener().
É possível ter ao mesmo tempo um ouvinte e um método de retorno de chamada para um objeto View. Se isso ocorrer,
o sistema chamará primeiro o ouvinte. O sistema não chamará o método de retorno de chamada a menos que o
ouvinte retorne false.
A combinação do método onDragEvent(DragEvent)
e View.OnDragListener é análoga à combinação
de onTouchEvent()
e View.OnTouchListener usados com eventos de toque.
Eventos de arrastar
O sistema envia um evento de arrastar como um objeto DragEvent. O
objeto tem um tipo de ação que informa ao ouvinte o que está ocorrendo no processo de
arrastar e soltar. O objeto contém outros dados, dependendo do tipo de ação.
Para obter o tipo de ação, o ouvinte chama getAction(). Há
seis valores possíveis, definidos por constantes na classe DragEvent. Esses valores
estão listados na Tabela 1.
O objeto DragEvent também contém os dados fornecidos pelo aplicativo
ao sistema na chamada ao
startDrag().
Alguns dados são válidos apenas para determinados tipos de ação. Os dados que são válidos para cada tipo de
ação são resumidos na Tabela 2. Eles também são descritos em detalhe com o
evento em que são válidos na seção
Projetar uma operação de arrastar e soltar.
Tabela 1. Tipos de ação DragEvent
| getAction() value | Significado |
|---|---|
ACTION_DRAG_STARTED |
O ouvinte de eventos de arrastar do objeto View recebe esse tipo de ação de evento logo depois que o
aplicativo chama
startDrag() e
obtém uma sombra da ação de arrastar.
|
ACTION_DRAG_ENTERED |
O ouvinte de eventos de arrastar do objeto View recebe esse tipo de ação de evento assim que a sombra da ação de arrastar
entra na caixa delimitadora da View. Esse é o primeiro tipo de ação de evento recebido
pelo ouvinte quando a sombra da ação de arrastar entra na caixa delimitadora. Se o ouvinte quiser
continuar a receber eventos de arrastar para essa operação, deverá retornar um
true booleano ao sistema.
|
ACTION_DRAG_LOCATION |
O ouvinte de eventos de arrastar do objeto View recebe esse tipo de ação de evento depois de receber um evento
ACTION_DRAG_ENTERED enquanto a sombra da ação de arrastar ainda
está na caixa delimitadora da View.
|
ACTION_DRAG_EXITED |
O ouvinte de eventos de arrastar do objeto View recebe esse tipo de ação de evento depois de receber um
ACTION_DRAG_ENTERED e pelo menos um evento
ACTION_DRAG_LOCATION, depois que o usuário mover
a sombra da ação de arrastar para fora da caixa delimitadora da View.
|
ACTION_DROP |
O ouvinte de eventos de arrastar do objeto View recebe esse tipo de ação de evento quando o usuário
libera a sombra da ação de arrastar sobre o objeto View. Esse tipo de ação somente será enviado ao ouvinte
do objeto View se esse ouvinte retornou um true booleano como resposta ao evento de arrastar
ACTION_DRAG_STARTED. Esse tipo de ação não será
enviado se o usuário liberar a sombra da ação de arrastar em uma View cujo ouvinte não está registrado,
ou se o usuário liberar a sombra da ação de arrastar em qualquer área que não faça parte do layout
atual.
O ouvinte deverá retornar |
ACTION_DRAG_ENDED |
O ouvinte de eventos de arrastar do objeto View recebe esse tipo de ação
quando o sistema está encerrando a operação de arrastar. Esse tipo de ação não é necessariamente
precedido por um evento ACTION_DROP. Se o sistema enviou
um ACTION_DROP, o recebimento do
tipo de ação ACTION_DRAG_ENDED não significa que a
operação de soltar foi bem-sucedida. O ouvinte deve chamar
getResult() para obter o valor que foi
retornado como resposta de ACTION_DROP. Se um
evento ACTION_DROP não foi enviado,
getResult() retorna false.
|
Tabela 2. Dados válidos de DragEvent por tipo de ação
Valor de getAction() |
Valor de getClipDescription() |
Valor de getLocalState() |
Valor de getX() |
Valor de getY() |
Valor de getClipData() |
valor de 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 |
Os métodos getAction(),
describeContents(),
writeToParcel() e
toString() sempre retornam dados válidos.
Se um método não contiver dados válidos para um determinado tipo de ação, retornará
null ou 0 dependendo do tipo de resultado.
A sombra da ação de arrastar
Durante uma operação de arrastar e soltar, o sistema exibe uma imagem arrastada pelo usuário. Para o movimento de dados, essa imagem representa os dados sendo arrastados. Para outras operações, a imagem representa algum aspecto da operação de arrastar.
Essa imagem é denominada uma sombra da ação de arrastar. Ela é criada com métodos declarados para um objeto
View.DragShadowBuilder e então passada ao sistema quando uma
ação de arrastar é iniciada usando
startDrag().
Como parte de sua resposta a
startDrag(),
o sistema invoca os métodos de retorno de chamada que você definiu em
View.DragShadowBuilder para obter uma sombra da ação de arrastar.
A classe View.DragShadowBuilder tem dois construtores:
View.DragShadowBuilder(View)-
Esse construtor aceita qualquer um dos objetos
Viewdo aplicativo. O construtor armazena o objeto View no objetoView.DragShadowBuilder. Portanto, durante o retorno de chamada, você pode acessá-lo durante a construção da sombra da ação de arrastar. Ele não precisa ser associado à View (se houver) selecionada pelo usuário para iniciar a operação de arrastar.Se você usar esse construtor, não precisa estender
View.DragShadowBuildernem modificar seus métodos. Por padrão, você obterá uma sombra da ação de arrastar com a mesma aparência que a View passada como argumento, centralizada no local onde o usuário está tocando a tela. View.DragShadowBuilder()-
Se você usar esse construtor, nenhum objeto View estará disponível no
objeto
View.DragShadowBuilder(o campo é definido comonull). Se você usar esse construtor e não estenderView.DragShadowBuildernem modificar seus métodos, você obterá uma sombra da ação de arrastar invisível. O sistema não gera um erro.
A classe View.DragShadowBuilder tem dois métodos:
-
onProvideShadowMetrics() -
O sistema chama esse método imediatamente após a chamada de
startDrag(). Use-o para enviar ao sistema as dimensões e o ponto de contato da sombra da ação de arrastar. O método tem dois argumentos:- dimensões
-
Um objeto
Point. A largura da sombra da ação de arrastar é especificada emxe a altura emy. - ponto de contato
-
Um objeto
Point. O ponto de contato é o local dentro da sombra da ação de arrastar que deve estar sob o dedo do usuário durante a ação de arrastar. Sua posição X é especificada emxe sua posição Y emy
-
onDrawShadow() -
Imediatamente após a chamada de
onProvideShadowMetrics()o sistema chamaonDrawShadow()para obter a sombra da ação de arrastar. O método tem um único argumento, um objetoCanvasque o sistema constrói com base nos parâmetros informados emonProvideShadowMetrics()Use-o para desenhar a sombra da ação de arrastar no objetoCanvasfornecido.
Para melhorar o desempenho, use um tamanho pequeno para a sombra da ação de arrastar. Para um único item, você pode usar um ícone. Para uma seleção múltipla, você pode usar ícones em uma pilha em vez de imagens completas espalhadas pela tela.
Projetar uma operação de arrastar e soltar
Esta seção mostra detalhadamente como iniciar uma ação de arrastar, como responder a eventos durante a ação de arrastar, como responder a um evento de largar e como encerrar a operação de arrastar e largar.
Iniciar uma ação de arrastar
O usuário inicia uma ação de arrastar com um gesto de arrastar — normalmente, uma pressão longa — em um objeto View. Como resposta, você deve fazer o seguinte:
-
Se necessário crie um
ClipDatae umClipData.Itempara os dados sendo movidos. Como parte do objeto ClipData, forneça metadados armazenados em um objetoClipDescriptiondentro do ClipData. Para uma operação de arrastar e soltar que não representa movimento de dados, você pode usarnullem vez de um objeto real.Por exemplo: este snippet de código mostra como responder a uma pressão longa em uma ImageView criando um objeto ClipData que contém a tag ou o rótulo de uma ImageView. Depois desse snippet, o próximo snippet mostra como modificar os métodos em
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) ); } } -
O snippet de código a seguir define
myDragShadowBuilderEle cria uma sombra da ação de arrastar para arrastar uma TextView como um retângulo cinza pequeno: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); } }Observação: Lembre-se de que não é necessário estender
View.DragShadowBuilder. O construtorView.DragShadowBuilder(View)cria uma sombra da ação de arrastar padrão com o mesmo tamanho do argumento View passado a ele, com o ponto de contato centralizado na sombra da ação de arrastar.
Responder a um início de ação de arrastar
Durante a operação de arrastar, o sistema despacha eventos de arrastar aos ouvintes de eventos de arrastar
dos objetos View no layout atual. Os ouvintes devem reagir
chamando getAction() para obter o tipo de ação.
No início de uma ação de arrastar, esse método retorna ACTION_DRAG_STARTED.
Em resposta a um evento com o tipo de ação ACTION_DRAG_STARTED,
um ouvinte poderia fazer o seguinte:
-
Chamar
getClipDescription()para obter aClipDescription. Usar os métodos de tipo MIME emClipDescriptionpara ver se o ouvinte pode aceitar os dados sendo arrastados.Se a operação de arrastar e soltar não representar movimento de dados, talvez isso não seja necessário.
-
Se o ouvinte puder aceitar uma ação de soltar, deverá retornar
true. Isso instrui o sistema a continuar a enviar eventos de arrastar ao ouvinte. Se ele não puder aceitar uma ação de soltar, deverá retornarfalsee o sistema deixará de enviar eventos de arrastar até enviarACTION_DRAG_ENDED.
Observe que para um evento ACTION_DRAG_STARTED,
os métodos de DragEvent a seguir não são válidos:
getClipData(), getX(),
getY() e getResult().
Processar eventos durante a ação de arrastar
Durante a ação de arrastar, os ouvintes que retornaram true como resposta ao
evento de arrastar ACTION_DRAG_STARTED continuam recebendo eventos de
arrastar. Os tipos de eventos de arrastar recebidos pelo ouvinte durante a ação de arrastar dependem da localização
da sombra da ação de arrastar e da visibilidade da View do ouvinte.
Durante a ação de arrastar, os ouvintes usam principalmente eventos de arrastar para decidir se devem alterar a aparência da View.
Durante a ação de arrastar, getAction() retorna um dentre três
valores:
-
ACTION_DRAG_ENTERED: O ouvinte recebe esse valores quando o ponto de contato (o ponto da tela sob o dedo do usuário) entrou na caixa delimitadora da View do ouvinte. -
ACTION_DRAG_LOCATION: Após receber um eventoACTION_DRAG_ENTEREDe antes de receber um eventoACTION_DRAG_EXITED, o ouvinte receberá um novo eventoACTION_DRAG_LOCATIONsempre que o ponto do contato se mover. Os métodosgetX()egetY()retornam as coordenadas X e Y do ponto de contato. -
ACTION_DRAG_EXITED: Esse evento é enviado a um ouvinte que recebeu previamenteACTION_DRAG_ENTERED, depois que a sombra da ação de arrastar não estava mais dentro da caixa delimitadora da View do ouvinte.
O ouvinte não precisa reagir a nenhum desses tipos de ação. Se o ouvinte retornar um valor para o sistema, ele será ignorado. Veja a seguir algumas diretrizes para responder a cada um desses tipos de ação:
-
Como reposta a
ACTION_DRAG_ENTEREDouACTION_DRAG_LOCATION, o ouvinte pode alterar a aparência da View para indicar que receberá em breve uma ação de soltar. -
Um evento com o tipo de ação
ACTION_DRAG_LOCATIONcontém dados válidos paragetX()egetY(), correspondentes à localização do ponto de contato. O ouvinte poderá usar essas informações para alterar a aparência da parte da View que está no ponto de contato. O ouvinte também poderá usar essas informações para determinar a posição exata em que o usuário vai soltar a sombra da ação de arrastar. -
Como resposta a
ACTION_DRAG_EXITED, o ouvinte deve redefinir todas as alterações de aparência aplicadas como resposta aACTION_DRAG_ENTEREDouACTION_DRAG_LOCATION. Isso indica ao usuário que a View deixou de ser um destino para uma ação de soltar iminente.
Responder a uma ação de soltar
Quando o usuário liberar a sombra da ação de arrastar em uma View no aplicativo, e a View tiver informado
previamente que poderia aceitar o conteúdo sendo arrastado, o sistema despachará um evento de arrastar
a essa View com o tipo de ação ACTION_DROP. O ouvinte
deve fazer o seguinte:
-
Chamar
getClipData()para obter o objetoClipDataoriginalmente fornecido na chamada destartDrag()e armazená-lo. Se as operações de arrastar e soltar não representarem movimento de dados, talvez isso não seja necessário. -
Retorne um
truebooleano para indicar que a ação de soltar foi processada corretamente ou, caso contrário,false. O valor retornado se torna o valor retornado porgetResult()para um eventoACTION_DRAG_ENDED.Observe que se o sistema não enviar um evento
ACTION_DROP, o valor degetResult()para umACTION_DRAG_ENDEDevento seráfalse.
Para um evento ACTION_DROP,
getX() e getY()
retornam as posições X e Y do ponto da ação de arrastar no momento da ação de soltar, usando o sistema
de coordenadas da View que recebeu a ação de soltar.
O sistema permite que o usuário libere a sombra da ação de arrastar em uma View cujo ouvinte não está
recebendo eventos de arrastar. Além disso, ele também permite que o usuário libere a sombra da ação de arrastar
em regiões vazias da IU do aplicativo ou em áreas fora do aplicativo.
Em todos esses casos, o sistema não envia um evento com o tipo de ação
ACTION_DROP, embora envie um evento
ACTION_DRAG_ENDED.
Responder a um fim de ação de arrastar
Imediatamente depois da liberação da sombra da ação de arrastar pelo usuário, o sistema envia um
evento de arrastar a todos os ouvintes de eventos de arrastar no aplicativo com um tipo de ação
ACTION_DRAG_ENDED. Isso indica que a operação de arrastar foi
concluída.
Cada ouvinte deve fazer o seguinte:
- Se um ouvinte alterou a aparência do objeto View durante a operação, deve redefinir a View para a sua aparência padrão. Isso é uma indicação visual para o usuário de que a operação foi concluída.
-
Opcionalmente, o ouvinte pode chamar
getResult()para obter mais informações sobre a operação. Se um ouvinte retornoutruecomo resposta de um evento do tipo de açãoACTION_DROP,getResult()retornarátruebooleano. Em todos os outros casos,getResult()retornaráfalsebooleano, inclusive todos os casos em que o sistema não enviou um eventoACTION_DROP. -
O ouvinte deve retornar
truebooleano ao sistema.
Responder a eventos de arrastar: um exemplo
Todos os eventos são recebidos inicialmente pelo método ou ouvinte de eventos de arrastar. O snippet de código a seguir é um exemplo simples da reação a eventos de arrastar em um ouvinte:
// 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;
}
};