Sekula1991 February 2016

RecyclerView drag & drop via itemTouchHelper bahaving strange when dragging fast

I've been following guide from this link "Drag and Swipe with RecyclerView - by IPaulPro" and i am having few problems on some situations.

So, i basically did all that he explained + i added a TextView in item that represents the position of an item in RecyclerView, something like this: enter image description here

Everything appears nice except when i start "sling shooting" items fast, then i have two problems:

  1. It happens to have a duplicate of numbers. enter image description here

    Also what i did was using notifyAdapterSetChanged() in the onItemClear() method - it fixed it in a way, but caused IllegalStateException, which catched - would lead to IndexOutOfBounds exception.

  2. Ocasionally,when swiped too fast, item gets in the "background". This can only be seen if items are not the same size. enter image description here

I will paste my whole adapter code below, there must be a flaw somewhere in it.

LayoutInflater inflater;
Context context;
AndroidEntityQuestionResult androidEntityQuestionResult;
ArrayList<AndroidEntityAnswer> list = new ArrayList<>();
ORDLayoutManagerQuestion ord;
ScreenDimensionsConstants sdc;


public OrderingRecycleAdapter(Context context, AndroidEntityQuestionResult androidEntityQuestionResult, ORDLayoutManagerQuestion ord) {
    inflater = LayoutInflater.from(context);
    this.context = context;
    this.list = androidEntityQuestionResult.getAndroidEntityQuestion().getEntityAnswer();
    t        

Answers


Doron Yakovlev-Golani February 2016

To me it seems like your onItemMove() does not account for all the changes. When something moves for more than one item (lets say between A & B), you are are swapping all the items between the two. However you report changes only to A & B and not to the rest of the elements in between.

I suggest you write a swap method that reports all the changes:

public boolean swapItems(int fromPosition, int toPosition){
    Collections.swap(list, fromPosition, toPosition);
    notifyItemMoved(fromPosition, toPosition);
    notifyItemMoved(toPosition, fromPosition);
    // And maybe also notifyItemChanged() as the item changes due to the shift
    notifyItemChanged(fromPosition);
    notifyItemChanged(toPosition);
}

Call this function instead of Collections.swap() and remove the rest of the notify code.


ankitagrawal February 2016

Change your onitemmove method

@Override
public boolean onItemMove(int fromPosition, int toPosition) {
    if (fromPosition < toPosition) {
        for (int i = fromPosition; i < toPosition; i++) {
            Collections.swap(list, i, i + 1);
        }
    } else {
        for (int i = fromPosition; i > toPosition; i--) {
            Collections.swap(list, i, i - 1);
        }
    }
    notifyItemMoved(fromPosition, toPosition);
    notifyItemChanged(fromPosition);
    return true;
}

to:

@Override
public boolean onItemMove(int fromPosition, int toPosition) {
    if (fromPosition < toPosition) {
        for (int i = fromPosition; i < toPosition; i++) {
            Collections.swap(list, i, i + 1);
        }
    } else {
        for (int i = fromPosition; i > toPosition; i--) {
            Collections.swap(list, i, i - 1);
        }
    }
    notifyItemMoved(fromPosition, toPosition);
    return true;
}


User0123456789 February 2016

To me it seems like your onItemMove() does not account for all the changes. When something moves for more than one item (lets say between A & B), you are are swapping all the items between the two. However you report changes only to A & B and not to the rest of the elements in between.

I suggest you write a swap method that reports all the changes:

public boolean swapItems(int fromPosition, int toPosition){
Collections.swap(list, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
notifyItemMoved(toPosition, fromPosition);
// And maybe also notifyItemChanged() as the item changes due to the shift
notifyItemChanged(fromPosition);
notifyItemChanged(toPosition);

}

Post Status

Asked in February 2016
Viewed 3,306 times
Voted 9
Answered 3 times

Search




Leave an answer