Search code examples
javaandroidandroid-recyclerviewitemtouchhelper

How to use ItemTouchHelper properly


I'm trying to use a RecyclerView with ItemTouchHelper for basic “drag & drop” and “swipe-to-dismiss” implementation. Swipe works correctly, items are deleted in adapter correctly, animation is correct, but “drag & drop” behaviour is very strange. After long click view isn't moving, however swapping items in adapter are correct.

this is how it works in my RecyclerView

and this is what I want

This code in my presenter, onSelectedChanged and clearView only to demonstrate clearly how items are selected.

    addedCitiesRecycler.setLayoutManager(llmAddedCities);

    adapterAddedCities = new AdapterAddedCities();


    ItemTouchHelper.SimpleCallback callback = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.START | ItemTouchHelper.END) {
        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            adapterAddedCities.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
            return true;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            adapterAddedCities.onItemDismiss(viewHolder.getAdapterPosition());
        }

        @Override
        public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
            if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
                AdapterAddedCities.ViewHolder holder = (AdapterAddedCities.ViewHolder) viewHolder;
                holder.itemView.setBackgroundColor(Color.LTGRAY);
            }
            super.onSelectedChanged(viewHolder, actionState);
        }

        @Override
        public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            AdapterAddedCities.ViewHolder holder = (AdapterAddedCities.ViewHolder) viewHolder;
            holder.itemView.setBackgroundColor(0);
        }
    };

    itemTouchHelper = new ItemTouchHelper(callback);
    itemTouchHelper.attachToRecyclerView(addedCitiesRecycler);

this methods in my adapter

public void onItemDismiss(int position) {
    citiesData.remove(position);
    notifyItemRemoved(position);
}

public void onItemMove(int fromPosition, int toPosition) {
    CityInfo tmp = citiesData.remove(fromPosition);
    citiesData.add(toPosition > fromPosition ? toPosition - 1 : toPosition, tmp);
    notifyItemMoved(fromPosition, toPosition);
}

Solution

  • I've updated com.android.support:recyclerview-v7:26.0.0-alpha1 to com.android.support:recyclerview-v7:27.0.0 in build.gradle and it works fine.

    I think it was bug in the library, so if you face the same issue, just update the library to the latest version.