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 objetosView
no layout atual. Para continuam recebendo eventos de arrastar, incluindo possível evento: o listener de eventos de arrastar precisa retornartrue
. 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 objetoView
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çãoACTION_DRAG_ENDED
. Ao retornarfalse
, 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çãoACTION_DRAG_ENTERED
: o listener pode reagir destacando oView
. - 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 parastartDragAndDrop()
que inicia a operação. O listener é espera-se que retorne o valor booleanotrue
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 umView
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 arrastarACTION_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çãoACTION_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 oACTION_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:
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 |
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.
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 objetoView
no objetoView.DragShadowBuilder
para que os callbacks possam o acessar a fim de construir a ação de arrastar. A visualização não precisa ser umaView
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 aView
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 objetoView.DragShadowBuilder
. O campo está definido comonull
. Você precisa estenderView.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
:umPoint
objeto. A largura da sombra da ação de arrastar éx
, e sua altura vai emy
outShadowTouchPoint
:um objetoPoint
. 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 emx
, e a posição Y aparece emy
.onDrawShadow()
Imediatamente após a chamada do método
onProvideShadowMetrics()
, o sistema chamaonDrawShadow()
para criar a ação de arrastar. O método tem um único da instância, um objetoCanvas
que as construções do sistema a partir dos parâmetros que você fornece noonProvideShadowMetrics()
. O método desenha a sombra da ação de arrastar noCanvas
:
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 objetoContentInfo
. A invoca oOnReceiveContentListener
.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.