1
resposta

[Reclamação] ItemTouchHelper Drag não funciona.

Bom dia.

Após pesquisar e tentar um solução por dias, consegui fazer com que o comportamento de pressionar, arrastar e soltar funciona-se. Descobri que ele tem um tempo para começar a funcionar e não foi citado no vídeo. Gostaria de saber como reduzir ou manipular este tempo pois isso ficou confuso e eu achei que não estava funcionando o comportamento esperado.

Outro fato é que os parâmetros e ordem dos mesmo estão diferentes do esperado:

@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
return makeMovementFlags(dragFlags, swipeFlags);
}

Obrigado.

Garanta sua matrícula hoje e ganhe + 2 meses grátis

Continue sua jornada tech com ainda mais tempo para aprender e evoluir

Quero aproveitar agora
1 resposta

Oi, Maycon! Como vai?

O ItemTouchHelper inicia o drag por long press quando isLongPressDragEnabled() == true. Esse "tempo" é o long press timeout do sistema (ViewConfiguration.getLongPressTimeout()). Não dá para reduzir esse timeout diretamente, mas você pode iniciar o drag na hora chamando itemTouchHelper.startDrag(viewHolder) e desativando o long press padrão.

Ajuste seu código assim:


// 1) Crie o SimpleCallback informando dragDirs e swipeDirs
ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(
        ItemTouchHelper.UP | ItemTouchHelper.DOWN,  // dragDirs
        ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT // swipeDirs
) {
    @Override
    public boolean onMove(@NonNull RecyclerView rv,
                          @NonNull RecyclerView.ViewHolder from,
                          @NonNull RecyclerView.ViewHolder to) {
        // troque itens na lista e notifique o adapter
        return true;
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder vh, int direction) {
        // remova ou trate o swipe
    }

    // Desative o long-press padrão para que o startDrag manual funcione
    @Override
    public boolean isLongPressDragEnabled() {
        return false;
    }
};

// 2) Anexe o ItemTouchHelper ao RecyclerView
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);

// 3) No ViewHolder (ou no Adapter), inicie o drag imediatamente ao tocar no "handle"
holder.handleView.setOnTouchListener((v, event) -> {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        itemTouchHelper.startDrag(holder);
        return true;
    }
    return false;
});

O que este código faz: desabilita o long press padrão e inicia o arrastar imediatamente quando o usuário toca no "handle", evitando o atraso do sistema.

Se quiser um pequeno atraso customizado (ex.: 120ms), use um postDelayed:


holder.handleView.setOnTouchListener((v, event) -> {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        v.postDelayed(() -> itemTouchHelper.startDrag(holder), 120);
        return true;
    }
    return false;
});

Sobre a ordem dos parâmetros: no makeMovementFlags(dragFlags, swipeFlags) a ordem é drag primeiro, swipe depois. Seu getMovementFlags está correto. Alternativamente, você pode pular o getMovementFlags e passar os dragDirs e swipeDirs direto no SimpleCallback(...) como mostrado no exemplo.

Exemplo de uso do getMovementFlags:


@Override
public int getMovementFlags(@NonNull RecyclerView rv, @NonNull RecyclerView.ViewHolder vh) {
    int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
    int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
    return makeMovementFlags(dragFlags, swipeFlags);
}

Dicas:

  • Quer arrastar só com "handle"? Deixe isLongPressDragEnabled() = false e chame startDrag no toque do handle.
  • Quer long press padrão? Retorne true em isLongPressDragEnabled() e não chame startDrag manualmente (vai respeitar o timeout do sistema).
  • Movimentos diferentes por tipo de item? Decida os flags no getMovementFlags conforme o viewType.

Espero ter ajudado. Conte com o apoio do Fórum na sua jornada. Fico à disposição.

Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado