O Jetpack Compose oferece suporte a arrastar e soltar com dois modificadores:
dragAndDropSource
: especifica um elemento combinável como o ponto de partida do gesto de arrasto.dragAndDropTarget
: especifica um elemento combinável que aceita os dados transferidos.
Por exemplo, para permitir que os usuários arrastem uma imagem no app, crie um elemento
combinável de imagem e adicione o modificador dragAndDropSource
. Para configurar um destino de soltar,
crie outro elemento combinável de imagem e adicione o modificador dragAndDropTarget
.
Os modificadores podem ser aplicados a várias origens de arrasto e vários destinos de soltar.
Os modificadores permitem que os apps compartilhem dados entre dois ou mais elementos combináveis usando
ClipData
, que é interoperável com implementações de View
.
Especificar uma origem de arrasto
Para ativar eventos de arrasto dentro de um componente, adicione o modificador dragAndDropSource
.
Ela usa uma função como parâmetro. Dentro dessa função, use
DragAndDropTransferData
para representar os dados transferíveis. Os dados podem
ser um URI remoto, dados de texto avançado na área de transferência, um arquivo local ou mais, mas
todos precisam ser agrupados em um objeto ClipData
. Forneça texto simples, por exemplo, da seguinte maneira:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ) ) }
Para permitir que a ação de arrastar cruze as bordas do app, o
construtor DragAndDropTransferData
aceita um argumento flags
. No
exemplo abaixo, a constante DRAG_FLAG_GLOBAL
especifica que os dados podem
ser arrastados de um app para outro:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ), flags = View.DRAG_FLAG_GLOBAL ) }
DragAndDropTransferData
aceita flags aceitas pelo sistema de visualização do Android.
Consulte a lista de constantes de visualização para conferir uma lista completa de flags disponíveis.
Receber dados de entrega
Atribua o modificador dragAndDropTarget
a um elemento combinável para permitir que ele
receba eventos de arrastar e soltar. O modificador tem dois parâmetros: o primeiro atua
como um filtro e especifica o tipo de dados que o modificador pode aceitar, e o
segundo envia os dados em um callback.
A instância do callback precisa ser gravada. O snippet abaixo mostra como lembrar o callback:
val callback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { // Parse received data return true } } }
Para aceitar dados de outros apps, use a requestDragAndDropPermission
para
ativar a recepção e libere quando terminar:
val externalAppCallback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { val permission = activity.requestDragAndDropPermissions(event.toAndroidDragEvent()) // Parse received data permission?.release() return true } } }
É importante lembrar que o DragAndDropEvent
retornado do callback do Compose
é diferente do esperado pelo método requestDragAndDropPermission
.
Portanto, é necessário chamar a função de extensão toAndroidDragEvent()
no parâmetro antes
de transmiti-la à solicitação de permissão.
O snippet a seguir demonstra como lidar com o texto simples descartado:
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = callback // or externalAppCallback )
A função de callback precisa retornar true
se o evento for consumido ou false
se o evento for recusado e não for propagado para o componente pai.
Processar eventos de arrastar e soltar
Substitua callbacks na interface DragAndDropTarget
para observar quando um
evento de arrastar e soltar começa, termina ou entra ou sai de um componente para controlar
precisamente a interface e o comportamento do app:
object : DragAndDropTarget { override fun onStarted(event: DragAndDropEvent) { // When the drag event starts } override fun onEntered(event: DragAndDropEvent) { // When the dragged object enters the target surface } override fun onEnded(event: DragAndDropEvent) { // When the drag event stops } override fun onExited(event: DragAndDropEvent) { // When the dragged object exits the target surface } override fun onDrop(event: DragAndDropEvent): Boolean = true }
Outros recursos
Codelab: Arrastar e soltar no Compose