Drag-and-Drop — como o arrastar e soltar funciona em aplicativos móveis

Autor: IT Sectr Publicado: 2026-02-27 Tempo de leitura: 9 min

Drag-and-Drop — um gesto interativo para arrastar um objeto visual pela tela com o dedo. O gesto consiste em três fases: agarrar (long press ou toque), mover (deslocar o dedo com o objeto) e soltar (largar na zona alvo). É usado para reordenar elementos, mover arquivos entre pastas e organizar interfaces (drag to reorder, drag to resize). No iOS é implementado através de UIDragInteraction, no Android — através de DragEvent e startDragAndDrop.

Principais pontos

  • Três fases — Drag-and-Drop consiste em agarrar, mover e soltar um objeto
  • UIDragInteraction — a classe principal do iOS para iniciar e manipular arrasto
  • startDragAndDrop — o método Android View para iniciar um arrasto após agarrar
  • Drag shadow — uma sombra visual do objeto arrastado que segue o dedo
  • Drop target — a zona de destino que destaca quando o objeto arrastado passa sobre ela

O que é Drag-and-Drop?

Drag-and-Drop (DnD) é um método de manipulação de elementos gráficos de interface onde o usuário agarra um objeto com o dedo ou mouse, move-o para outra posição e o solta. Em interfaces móveis, o Drag-and-Drop geralmente é iniciado por um toque longo — o usuário mantém o elemento pressionado por 300–500 ms, após o qual o sistema muda a interface para o modo de arrasto, e o movimento do dedo desloca o objeto.

Historicamente, o Drag-and-Drop originou-se em interfaces desktop (Xerox Star, 1981; Macintosh, 1984) como alternativa aos comandos copiar/colar. Em plataformas móveis, o suporte completo apareceu no iOS 11 (2017) com UIDragInteraction e no Android 7.0 (2016) com Multi-Window Drag-and-Drop. Antes disso, o arrasto em aplicativos móveis era implementado por soluções personalizadas através de reconhecedores de gestos.

Conceitos-chave: sessão de arrasto (drag session), itens arrastáveis (drag items), visualização de arrasto (drag preview — representação visual do objeto), zona de destino (drop target), proposta de destino (drop proposal — ação ao soltar: mover, copiar, vincular). O sistema gerencia a sessão no nível do sistema operacional, permitindo arrastar objetos entre diferentes aplicativos (por exemplo, uma foto da Galeria para o Notas).

Fases do Drag-and-Drop

Drag-and-Drop é dividido em três fases sequenciais. Fase 1 — Agarrar (Início do Arrasto): o usuário inicia o gesto (geralmente Long Press), o sistema cria uma sessão de arrasto, captura os dados do objeto e exibe uma visualização de arrasto — uma cópia semitransparente do elemento que segue o dedo. Nesta fase, o sistema rejeita outros gestos (rolagem, seleção de texto) até que o DnD seja concluído.

Fase 2 — Mover (Movimento do Arrasto): o dedo se move pela tela, a visualização de arrasto segue o ponto de toque. O sistema determina continuamente o destino sob o dedo e envia eventos de drag-enter, drag-move e drag-exit. O destino pode reagir visualmente: destacar, expandir ou mostrar uma linha de inserção. Esta fase dura de 0,5 a 10+ segundos dependendo da complexidade da tarefa.

Fase 3 — Soltar (Queda): o dedo é levantado da tela. O sistema finaliza a sessão de arrasto e chama o callback de destino. Se o destino rejeitar a queda (por exemplo, arrastar um arquivo para uma pasta sem permissões de escrita), a visualização de arrasto retorna animadamente à posição original (animação de cancelamento). Se a queda for aceita, o elemento desaparece da posição original e aparece no destino.

FaseEvento iOSEvento AndroidEstado visual
AgarrarUIDragInteractionDelegate.dragSessionWillBeginView.OnLongClickListener → startDragAndDropVisualização de arrasto aparece sob o dedo
MoverUIDropInteractionDelegate.dragSessionDidUpdateView.OnDragListener.onDrag (ACTION_DRAG_MOVED)Visualização se move, destino destaca
SoltarUIDropInteractionDelegate.performDropView.OnDragListener.onDrag (ACTION_DROP)Animação de queda ou retorno

Arrasto entre aplicativos é um recurso disponível em ambas as plataformas. O iOS suporta Drag-and-Drop entre aplicativos no modo Split View e Slide Over (iPad). O Android suporta arrasto entre aplicativos no modo Split Screen. Os dados são transferidos via UIPasteConfiguration (iOS) ou ClipData (Android). O desenvolvedor especifica os tipos de dados suportados (UTI para iOS, MIME para Android).

Drag-and-Drop no iOS: UIDragInteraction

UIDragInteraction é a principal API do iOS para arrasto, adicionada no iOS 11. Para habilitar o arrasto de uma View, adicione UIDragInteraction com UIDragInteractionDelegate. O delegado define quais elementos são arrastáveis, sua aparência e comportamento. Para receber elementos, use UIDropInteraction com UIDropInteractionDelegate, que determina se a View pode aceitar uma queda e como processar os dados.

swift
// UIDragInteraction — arrastar um elemento de uma coleção
class DragViewController: UIViewController, UIDragInteractionDelegate {

    @IBOutlet var dragSourceView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let dragInteraction = UIDragInteraction(delegate: self)
        dragSourceView.addInteraction(dragInteraction)
    }

    func dragInteraction(_ interaction: UIDragInteraction,
                          itemsForBeginning session: UIDragSession) -> [UIDragItem] {

        guard let data = Data(contentsOf: selectedFileURL) else { return [] }

        let itemProvider = NSItemProvider(object: data as NSData)
        let dragItem = UIDragItem(itemProvider: itemProvider)

        // Visualização de arrasto — uma cópia reduzida do elemento
        dragItem.previewProvider = {
            let previewView = UIImageView(image: thumbnailImage)
            previewView.alpha = 0.8
            return UIDragPreview(view: previewView)
        }
        return [dragItem]
    }
}

UIDropInteractionDelegate é a interface espelho para receber quedas. O método canHandle(_:) verifica se o tipo de dado é suportado. sessionDidUpdate(_:) atualiza visualmente o estado (destaque, linha de inserção). performDrop(_:) realiza o processamento final dos dados. O iOS chama automaticamente UIDropProposal com o tipo de operação: .move, .copy, ou .forbidden. O tipo de operação afeta a exibição visual (um ícone + no canto da visualização para cópia, um sinal de proibição para forbidden).

Drag-and-Drop no Android: startDragAndDrop

View.startDragAndDrop() é o método do Android SDK para iniciar um arrasto, disponível desde a API 24 (Android 7.0). É chamado após agarrar o elemento (geralmente em onLongClick). Parâmetros: ClipData (dados), DragShadowBuilder (sombra visual), Object myLocalState (estado local), flags. DragShadowBuilder cria um Bitmap que segue o dedo. O sistema gerencia automaticamente as animações e os eventos de toque durante o arrasto.

kotlin
// Drag-and-Drop de um elemento RecyclerView com reordenação
class ReorderAdapter(private val items: MutableList<String>) :
    RecyclerView.Adapter<ReorderAdapter.ViewHolder>() {

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.itemView.setOnLongClickListener {
            // Criando ClipData para transferência de dados
            val clipData = ClipData.newPlainText("item", items[position])

            // DragShadowBuilder personalizado com visualização reduzida
            val shadowBuilder = object : View.DragShadowBuilder(holder.itemView) {
                override fun onProvideShadowMetrics(shadowSize: Point, shadowTouchPoint: Point) {
                    shadowSize.set(itemView.width, itemView.height / 2)
                }
            }

            holder.itemView.startDragAndDrop(clipData, shadowBuilder, position, 0)
            true
        }
    }
}

Recebimento de queda no Android é implementado através de View.setOnDragListener(). O listener recebe eventos ACTION_DRAG_STARTED, ACTION_DRAG_ENTERED, ACTION_DRAG_LOCATION, ACTION_DRAG_EXITED, ACTION_DROP e ACTION_DRAG_ENDED. No evento ACTION_DROP, os dados são extraídos do ClipData e a ação alvo é executada. Para RecyclerView com reordenação, recomenda-se ItemTouchHelper.SimpleCallback — um mecanismo embutido que lida automaticamente com Long Press para agarrar, animação de movimento e os métodos utilitários onMove/onSwiped.

Casos de uso do Drag-and-Drop

Reordenação de listas (drag to reorder) é o cenário DnD mais comum: os usuários arrastam itens da lista para alterar sua ordem. Exemplos: reorganizar contatos nos favoritos, classificar tarefas em rastreadores (Trello, Todoist), reordenar faixas em uma playlist (Spotify, Apple Music). Implementado via ItemTouchHelper no Android ou UILongPressGestureRecognizer com reordenação de células no iOS.

Gerenciadores de arquivos — Drag-and-Drop para copiar e mover arquivos entre pastas. iOS Files App, Android Files by Google, Dropbox — todos suportam DnD. Arrastar um arquivo para uma pasta o move para dentro (move), arrastar com Option/Ctrl pressionado o copia (copy). O destino destaca visualmente ao passar o cursor, mostrando os limites da pasta.

Quadros Kanban — Trello, Jira, Notion usam Drag-and-Drop para mover cartões entre colunas (To Do → In Progress → Done). Ao arrastar, o cartão se desprende da coluna de origem, segue o dedo e, ao cruzar o limite de outra coluna, insere-se com animação. O iOS 11+ suporta UIDragPreview com efeito parallax, onde a visualização se inclina ligeiramente do ponto de toque, criando profundidade.

Seções Springboard (iOS) — arrastar ícones de aplicativos na tela inicial do iOS. Um toque longo em um ícone ativa o modo “tremendo” (os ícones balançam), após o qual o usuário pode mover ícones entre páginas e criar pastas. Este é um dos padrões de UX de DnD mais complexos, pois requer o manuseio simultâneo de arrasto, animação de tremor e agrupamento em pastas.

Recomendações de UX para Drag-and-Drop

Feedback visual é criticamente importante para Drag-and-Drop. O objeto arrastado deve mudar: encolher (iOS: escala 0.8–0.9), tornar-se semitransparente (alpha 0.7–0.8) e elevar-se sobre a interface com uma sombra (shadow offset). O destino deve reagir visualmente ao passar o cursor: destacar, expandir ou mostrar uma borda. Sem esses sinais, o usuário não consegue saber onde pode soltar o objeto.

Animação de retorno (cancelamento de arrasto) — se o usuário soltar o elemento fora da zona de queda ou sobre uma zona inválida, o objeto deve retornar animadamente à sua posição original. O iOS UIDragInteractionDelegate fornece dragInteraction(_:sessionDidMove:) para rastreamento e dragInteraction(_:session:willEndWith:) para animação de retorno. O Android View.setOnDragListener recebe ACTION_DRAG_ENDED, onde uma animação de retorno pode ser iniciada via ValueAnimator ou ObjectAnimator.

RecomendaçãoiOSAndroid
Agarrar por gestoLong Press (padrão)OnLongClickListener
Visualização de arrastoUIDragItem.previewProviderDragShadowBuilder
Feedback hápticoUIImpactFeedbackGeneratorHapticFeedbackConstants.LONG_PRESS
Animação de retornoUIDragPreviewTargetViewPropertyAnimator
Proposta de quedaUIDropProposal (.move/.copy)ACTION_DROP + flags
DnD entre aplicativosiOS 11+ Split View (iPad)Android 7.0+ Split Screen

Acessibilidade: usuários com limitações motoras podem não conseguir realizar o gesto de arrasto. Forneça alternativas através de botões “Mover para cima/baixo” para listas e um menu de contexto “Mover para pasta” para arquivos. O iOS VoiceOver suporta a ação de rotor “Arrastar” para mover elementos. O Android TalkBack fornece ações personalizadas através de AccessibilityNodeInfo.addAction(). Nike Run Club e Apple Health usam DnD para reordenar métricas no painel — com acesso através de botões padrão.

Perguntas frequentes

Qual gesto é usado para iniciar o Drag-and-Drop?

O gesto padrão para iniciar Drag-and-Drop é um toque longo de 300–500 ms. O iOS usa o mecanismo embutido UIDragInteraction que converte automaticamente um toque sustentado em um agarrar. O Android requer uma chamada explícita a startDragAndDrop() no callback OnLongClickListener. Em alguns casos (por exemplo, jogos), o DnD pode começar com um toque simples sem demora.

Objetos podem ser arrastados entre diferentes aplicativos?

Sim, Drag-and-Drop entre aplicativos é suportado no iOS 11+ (iPad) e Android 7.0+. No iPad, o arrasto funciona no modo Split View e Slide Over — o usuário pode pegar texto do Safari e soltá-lo no Notas. No Android, o DnD entre aplicativos funciona no Split Screen. Os dados são transferidos via UIPasteConfiguration (iOS) ou ClipData (Android) com tipos suportados especificados (UTI, MIME).

Como evitar o conflito entre Drag-and-Drop e rolagem?

O conflito DnD e Scroll é resolvido através de um atraso de agarre. Se o usuário começar a mover o dedo antes que o tempo limite do Long Press (500 ms) expire, o gesto é interpretado como rolagem em vez de Drag-and-Drop. No iOS, o UIDragInteraction gerencia automaticamente esse conflito através de cancelsTouchesInView. No Android, o ItemTouchHelper usa um limite — se o movimento exceder o limite TouchSlop, o Long Press é cancelado em favor da rolagem.

Que dados podem ser transferidos ao arrastar?

Drag-and-Drop suporta qualquer tipo de dado: texto, imagens, arquivos, URLs, objetos personalizados. O iOS usa NSItemProvider com tipos UTI (public.text, public.image, public.file-url). O Android usa ClipData com tipos MIME (text/plain, image/png, application/octet-stream). Para dados personalizados, um ClipData.Item com Intent é criado. Para DnD entre aplicativos, os dados são empacotados em formatos universais: texto simples, HTML, RTF, UIImage/PNG.

Como animar o retorno do elemento quando o Drag-and-Drop é cancelado?

No iOS, a animação de retorno é tratada através de UIDragPreviewTarget — a posição final para a qual a visualização retorna animadamente. No Android, use ViewPropertyAnimator com translateX/translateY para retornar o elemento à sua posição original. A duração da animação é de 200–300 ms com uma curva de easing (EaseOut). O UIKit adiciona automaticamente um UIDragPreview com efeito parallax que retorna suavemente quando o gesto é cancelado.

Resumo

  • Drag-and-Drop é um método de arrastar objetos com três fases: agarrar, mover, soltar
  • Início — geralmente através de Long Press (300–500 ms) para diferenciar da rolagem
  • API iOS — UIDragInteraction (origem) + UIDropInteraction (receptor)
  • API Android — View.startDragAndDrop() (origem) + View.setOnDragListener (receptor)
  • ItemTouchHelper — uma solução Android pronta para reordenar em RecyclerView
  • Visualização de arrasto — uma sombra visual do objeto seguindo o dedo com semitransparência
  • Animação de retorno — obrigatória ao soltar fora de uma zona válida para um UX claro

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também