Principais conceitos

As seções a seguir explicam alguns dos principais conceitos do processo de arrastar e soltar.

Processo de arrastar e soltar

Existem quatro etapas ou estados no processo de arrastar e soltar: iniciado, continuando, solto e finalizado.

Iniciado

Em resposta ao gesto de arrastar de um usuário, seu aplicativo chama startDragAndDrop() para instruir o sistema a iniciar uma operação de arrastar e soltar. A método fornecem o seguinte:

  • Os dados a serem arrastados.
  • Um callback para mostrar a ação de arrastar
  • Metadados que descrevem os dados arrastados
  • O sistema responde chamando o aplicativo para receber uma ação de arrastar sombra. Em seguida, o sistema mostra a ação de arrastar no dispositivo.
  • Em seguida, o sistema envia um evento de arrastar com tipo de ação ACTION_DRAG_STARTED até o evento de arrastar. listener de todos os objetos View no layout atual. Para continuam recebendo eventos de arrastar, incluindo possível evento: o listener de eventos de arrastar precisa retornar true. Isso registra o listener com o sistema. Somente listeners registrados continuam receber eventos de arrastar. Neste ponto, os listeners também podem alterar aparência do objeto View do destino de soltar para mostrar que a visualização pode aceitar um evento de soltar.
  • Se o listener de eventos de arrastar retornar false, ele não receberá a ação de arrastar. para a operação atual até que o sistema envie um evento de arrastar com o tipo de ação ACTION_DRAG_ENDED. Ao retornar false, o listener informa ao sistema que não está interessado na operação de arrastar e soltar e não quer aceitar os dados arrastados.
Em andamento
O usuário continua a arrastar. Conforme a sombra da ação de arrastar cruza caixa delimitadora de um destino de soltar, o sistema envia um ou mais eventos de arrastar para ao listener de eventos de arrastar do destino. O listener pode alterar a aparência o destino de soltar View em resposta ao evento. Por exemplo, se o evento indica que a sombra da ação de arrastar entra na caixa delimitadora da ação de soltar destino: tipo de ação ACTION_DRAG_ENTERED : o listener pode reagir destacando o View.
Solto
O usuário solta a ação de arrastar dentro da caixa delimitadora de uma ação de soltar alvo. O sistema envia ao listener do destino de soltar um evento de arrastar com ação. digite ACTION_DROP. O objeto de evento de arrastar contém os dados que são transmitidos ao sistema na chamada para startDragAndDrop() que inicia a operação. O listener é espera-se que retorne o valor booleano true ao sistema se o listener processa os dados soltos. : essa etapa ocorre apenas se o usuário soltar a sombra da ação de arrastar dentro do caixa delimitadora de um View cujo listener está registrado para receber eventos de arrastar. (um destino de soltar). Se o usuário soltar a sombra da ação de arrastar em qualquer outro situação, nenhum evento de arrastar ACTION_DROP é enviado.
Encerrado

Depois que o usuário solta a sombra da ação de arrastar e depois que o sistema envia

um evento de arrastar com o tipo de ação ACTION_DROP, se necessário, o sistema envia um evento de arrastar com tipo de ação ACTION_DRAG_ENDED para indicar que o arrastar e soltar foi concluída. Isso é feito independentemente de onde o usuário libera a sombra da ação de arrastar. O evento é enviado a todos os listeners registradas para receber eventos de arrastar, mesmo que o listener também receba o ACTION_DROP.

Cada uma dessas etapas é descrita em mais detalhes na seção chamada Uma operação de arrastar e soltar.

Eventos de arrastar

O sistema envia um evento de arrastar na forma de um objeto DragEvent, que contém um tipo de ação que descreve o que acontece no botão de arrastar e soltar de desenvolvimento de software. Dependendo do tipo de ação, o objeto também pode conter outros dados.

Os listeners de eventos de arrastar recebem o objeto DragEvent. Para ver o tipo de ação, os listeners chamam DragEvent.getAction(). Há seis valores possíveis, definidos por constantes na classe DragEvent: que estão descritos na tabela 1:

Tabela 1. Tipos de ação de DragEvent.

Tipo de ação Significado
ACTION_DRAG_STARTED O aplicativo chama startDragAndDrop() e recebe uma sombra de arraste. Se o listener quiser continuar recebendo eventos de arrastar para esta operação, ele deve retornar o booleano true ao sistema.
ACTION_DRAG_ENTERED A sombra da ação de arrastar entra na caixa delimitadora do elemento View: Esse é o primeiro tipo de ação de evento que o listener recebe quando a sombra da ação de arrastar entra na caixa delimitadora.
ACTION_DRAG_LOCATION Após um ACTION_DRAG_ENTERED, a ação de arrastar ainda está na caixa delimitadora do evento de arrastar View.
ACTION_DRAG_EXITED Seguindo uma ACTION_DRAG_ENTERED e pelo menos uma ACTION_DRAG_LOCATION, a sombra da ação de arrastar se move fora da caixa delimitadora do evento de arrastar View
ACTION_DROP A sombra da ação de arrastar se solta sobre o evento de arrastar, View: Este tipo de ação é enviado para um View ao listener do objeto somente se o listener retornar um valor booleano true em resposta ao ACTION_DRAG_STARTED evento de arrastar. Este tipo de ação não é enviado se o usuário soltar a ação de arrastar sobre uma View cujo listener não esteja registrado ou se o usuário soltar a ação de arrastar sombra sobre qualquer coisa que não faça parte do layout atual.

O listener vai retornar o valor booleano true se processa a ação de soltar. Caso contrário, ele deve retornar false:

ACTION_DRAG_ENDED O sistema está encerrando a operação de arrastar e soltar. Este tipo de ação não é necessariamente precedido por um evento ACTION_DROP. Se o sistema envia um ACTION_DROP, recebendo ACTION_DRAG_ENDED não implica que o descarte concluído. O listener precisa chamar getResult(), conforme mostrado na tabela 2, para obter o valor que é retornado em resposta a ACTION_DROP. Se um O evento ACTION_DROP não é enviado, então getResult() retorna false.

O objeto DragEvent também contém os dados e metadados que seu aplicativo fornece ao sistema na chamada para startDragAndDrop(). Alguns dos dados são válidos somente para determinados tipos de ação, conforme resumido na tabela 2. Para mais informações sobre eventos e seus dados associados, consulte a seção chamada Uma de arrastar e soltar.

Tabela 2. Dados válidos de DragEvent por tipo de ação

getAction()
valor
getClipDescription()
valor
getLocalState()
valor
getX()
valor
getY()
valor
getClipData()
valor
getResult()
valor
ACTION_DRAG_STARTED ✓ ✓        
ACTION_DRAG_ENTERED ✓ ✓        
ACTION_DRAG_LOCATION ✓ ✓ ✓ ✓    
ACTION_DRAG_EXITED ✓ ✓        
ACTION_DROP ✓ ✓ ✓ ✓ ✓  
ACTION_DRAG_ENDED   ✓       ✓

Os métodos DragEvent getAction(), describeContents(), writeToParcel(), e toString() sempre retornar dados válidos.

Se um método não contém dados válidos para um tipo de ação específico, ele retorna null ou 0, dependendo do tipo de resultado.

Ação de arrastar

Durante uma operação de arrastar e soltar, o sistema exibe uma imagem que o usuário se arrasta. 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.

A imagem é chamada de sombra de arrastar. Ela é criada com métodos que você declara para por View.DragShadowBuilder objeto. Você transmite o builder ao sistema quando inicia um processo de arrastar e soltar operação usando startDragAndDrop(). Como parte de sua resposta startDragAndDrop(), o sistema invoca os métodos de callback definidos no View.DragShadowBuilder para extrair uma ação de arrastar.

A classe View.DragShadowBuilder tem dois construtores:

View.DragShadowBuilder(View)

Esse construtor aceita todos os objetos View do aplicativo. O construtor armazena o objeto View no objeto View.DragShadowBuilder para que os callbacks possam o acessar a fim de construir a ação de arrastar. A visualização não precisa ser uma View que o usuário seleciona para iniciar a operação de arrastar.

Se você usar esse construtor, não vai precisa estender o View.DragShadowBuilder nem substituir os métodos dele. Por padrão, uma ação de arrastar uma sombra com a mesma aparência que a View transmitida como argumento. centralizada no local em que o usuário toca na tela.

View.DragShadowBuilder()

Se você usar esse construtor, nenhum objeto View estará disponível na objeto View.DragShadowBuilder. O campo está definido como null. Você precisa estender View.DragShadowBuilder e modifique os métodos. Caso contrário, você vai receber uma ação de arrastar invisível. O sistema não gera um erro.

A classe View.DragShadowBuilder tem dois métodos que, juntos, criam a ação de arrastar. sombra:

onProvideShadowMetrics()

O sistema chama esse método imediatamente após startDragAndDrop() ser chamado. Use o método para enviar as dimensões e o ponto de contato da ação de arrastar ao sistema. O método tem dois parâmetros:

outShadowSize:um Point objeto. A largura da sombra da ação de arrastar é x, e sua altura vai em y

outShadowTouchPoint:um objeto Point. O ponto de contato é o local na sombra da ação de arrastar que deve estar sob o dedo do usuário durante a ação de arrastar. A posição X aparece em x, e a posição Y aparece em y.

onDrawShadow()

Imediatamente após a chamada do método onProvideShadowMetrics(), o sistema chama onDrawShadow() para criar a ação de arrastar. O método tem um único da instância, um objeto Canvas que as construções do sistema a partir dos parâmetros que você fornece no onProvideShadowMetrics(). O método desenha a sombra da ação de arrastar no Canvas:

Para melhorar o desempenho, use um tamanho pequeno para a ação de arrastar. Para um único item, convém usar um ícone. Para uma seleção de vários itens, é possível querem usar ícones em uma pilha em vez de imagens completas espalhadas pela tela.

Listeners de eventos de arrastar e métodos de callback

Um View recebe eventos de arrastar com um listener de eventos de arrastar que implementa View.OnDragListener ou com o método de callback onDragEvent() da visualização. Quando o sistema chamar o método ou listener, ele fornece uma Argumento DragEvent.

Na maioria dos casos, é preferível usar um listener que um método de callback. Ao projetar IUs, você normalmente não cria subclasses de View, mas usar o método de callback força a criação de subclasses para substituir o método. Por comparação, você pode implementar uma classe de listener e a usar com vários objetos View diferentes. Também é possível implementá-la como uma classe inline anônima ou expressão lambda. Para definir o listener de um objeto View, chame setOnDragListener().

Como alternativa, você pode mudar a implementação padrão de onDragEvent(). sem substituir o método. Defina um OnReceiveContentListener em uma visualização para mais detalhes, consulte setOnReceiveContentListener() Por padrão, o método onDragEvent() faz o seguinte:

  • Retorna "true" em resposta à chamada para startDragAndDrop().
  • Ligações performReceiveContent() se os dados de arrastar e soltar forem soltos na visualização. Os dados são passados para a como um objeto ContentInfo. A invoca o OnReceiveContentListener.

  • Retorna "true" se os dados de arrastar e soltar são soltos na visualização e o O OnReceiveContentListener consome qualquer conteúdo.

Defina o OnReceiveContentListener para processar os dados especificamente para sua app. Para compatibilidade com versões anteriores até o nível 24 da API, use a versão Jetpack do OnReceiveContentListener

Você pode ter um listener de eventos de arrastar e um método de callback para um objeto View em caso em que o sistema primeiro chama o listener. O sistema não chama a menos que o listener retorne false.

A combinação do método onDragEvent() e View.OnDragListener é análoga à combinação das onTouchEvent() e View.OnTouchListener usada com eventos de toque.