10

I am using ItemTouchHelper and ItemTouchHelper.SimpleCallback to allow the user to reorder a vertical list Recycler View.

The drag and drop works but the drop is forced after the first jumped line even though I don't leave up my finger from the dragged cell.

Please find below the SimpleCallback :

private void initSwipeAndDrap() {

    ItemTouchHelper.SimpleCallback simpleItemTouchCallback =
            new ItemTouchHelper.SimpleCallback(
                    ItemTouchHelper.UP | ItemTouchHelper.DOWN,
                    0) {

                //========== Swipe (Not used) ==============

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


                //========== Drag ==============

                @Override
                public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {

                    int fromPosition = viewHolder.getAdapterPosition();
                    int toPosition = target.getAdapterPosition();

                    Podcast podcast = rva.podcasts.remove(fromPosition);
                    rva.podcasts.add(toPosition, podcast);
                    act.dmo.updatePodcastsListPosition();
                    act.dmo.notifyDataSetChangedPodcast();

                    return true;
                }

                @Override
                public boolean isLongPressDragEnabled() {
                    return false;
                }


            };

    itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
    itemTouchHelper.attachToRecyclerView(rv);
}
u2gilles
  • 6,888
  • 7
  • 51
  • 75

4 Answers4

6

Replacing notifyDataSetChanged() by notifyItemMoved() in onMove() method fixed my problem.

Which supprised me as I thought that onMove() was called after the drop. In fact, it has an effect on the drop itself.

u2gilles
  • 6,888
  • 7
  • 51
  • 75
  • I came across the problem. Thanks for posting the solution. – Malko Aug 10 '16 at 07:37
  • 1
    For those still not worked: [Why does my RecyclerView with ItemTouchHelper stop dragging after only one item, after overriding getItemViewType()?](https://stackoverflow.com/questions/39996110/why-does-my-recyclerview-with-itemtouchhelper-stop-dragging-after-only-one-item?rq=1) – nyconing Jan 09 '18 at 14:44
4

For those having the snaping problem when you move an element, if you are using this override

   @Override
    public int getItemViewType(int position) {
        return position;
    }

Just delete it from your adapter and it will work just fine

Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
0

I had similar problem when I used recycler with view pager and constraint layout. I tried those responses but only thing that helped me was setting:

viewBinding.recycler.setHasFixedSize(true)

This made possible dragging view from one end of recycler to another. Without it, every dragging was interrupted during scroll.

I got to this solution thanks to this post.

0

If you are using NestedScrollView just remove and instead of using other layouts use ConstraintLayout

Steps:

Use ConstrainLayout and RecylerView like this:

<androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rvDraggable"
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_0"
            android:layout_marginStart="@dimen/dp_16"
            android:layout_marginEnd="@dimen/dp_16"
            android:scrollbarStyle="outsideOverlay"
            android:scrollbars="none"
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

Note- you can also try to use:

  • viewBinding.recycler.setHasFixedSize(true)

  • If you are using notifyDataSetChanged() so just replace it by notifyItemMoved() in onMove() method