Search code examples
javaandroidandroid-recyclerviewmaterial-designitemtouchhelper

Hover event in RecyclerView using ItemTouchHelper


I have a RecyclerView and implemented drag and drop functionality using the ItemTouchHelper and ItemTouchHelper.Callback.

In ItemTouchHelper.Callback I have the callback method onMove() which gets called after the dragged view was dragged over the target view and the swap is completed.

What I am trying to implement (or find) is a new callback that is called when the dragged view is over the target view, before the swap is made. As you can see in the GIF below.

enter image description here

Any ideas how I can achieve this? Thanks!


Solution

  • I found a solution for the question that I asked so I'm gonna post it here.

    ItemTouchHelper.Callback has a method called choseDropTarget() which selects a drop target from the list of ViewHolders that are under the dragged view and it is called multiple times while dragging the view. Here we have information to calculate when the dragged view is hovering the view below and when the hovering stops.

    @Override
    public RecyclerView.ViewHolder chooseDropTarget(RecyclerView.ViewHolder selected, List<RecyclerView.ViewHolder> dropTargets, int curX, int curY) {
        for (RecyclerView.ViewHolder target : dropTargets) {
                int top = curY - selected.itemView.getTop();
                int bottom = curY + selected.itemView.getHeight();
                int diff;
                if (top < 0) {
                    diff = target.itemView.getTop() - curY;
                } else {
                    diff = target.itemView.getBottom() - bottom;
                }
                if (Math.abs(diff) <= 100) {
                    adapter.onItemHover();
                } else {
                    adapter.onItemHoverFinish();
                }
        }
        return super.chooseDropTarget(selected, dropTargets, curX, curY);
    }
    

    The method calculates the offset difference between the dragged view and the bottom view and if the difference is less than 100 onItemHover() callback is called and onItemHoverFinished() otherwise.

    Let me know if you have a more elegant approach for this issue. Thanks!