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:

Everything appears nice except when i start "sling shooting" items fast, then i have two problems:
It happens to have a duplicate of numbers.

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.
Ocasionally,when swiped too fast, item gets in the "background". This can only be seen if items are not the same size.

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();
    this.androidEntityQuestionResult = androidEntityQuestionResult;
    this.ord = ord;
    sdc = new ScreenDimensionsConstants(context);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.custom_row_ordering_rv, parent, false);
    final RecyclerView.ViewHolder holder = new OrderingViewHolder(view);
    return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof OrderingViewHolder) {
        ((OrderingViewHolder) holder).answerText.setText(list.get(position).getAnswer().getANSWER_TEXT());
        int currentPosition = position + 1;
        ((OrderingViewHolder) holder).position.setText("#" + currentPosition);
    }
}
@Override
public int getItemCount() {
    return list.size();
}
@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;
}
@Override
public void onItemDismiss(int position) {
}
@Override
public void onStartDrag(RecyclerView.ViewHolder viewHolder) {
        ord.getItemTouchHelper().startDrag(viewHolder);
}
class OrderingViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
    private TextView answerText;
    private ImageView pin;
    private TextView position;
    public OrderingViewHolder(View itemView) {
        super(itemView);
        answerText = (TextView) itemView.findViewById(R.id.orderingAnswer);
        answerText.setTextSize(TypedValue.COMPLEX_UNIT_PX, sdc.getHeight() / 40);
        pin = (ImageView) itemView.findViewById(R.id.ordering_pin);
        pin.getLayoutParams().width = sdc.getHeight() / 15;
        pin.getLayoutParams().height = sdc.getHeight() / 15;
        pin.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (MotionEventCompat.getActionMasked(event) ==
                        MotionEvent.ACTION_DOWN) {
                    OrderingRecycleAdapter.this.onStartDrag(OrderingViewHolder.this);
                }
                return false;
            }
        });
        position = (TextView) itemView.findViewById(R.id.answer_position);
        position.setTextSize(TypedValue.COMPLEX_UNIT_PX, sdc.getHeight() / 40);
    }
    @Override
    public void onItemSelected() {
        itemView.setBackgroundResource(R.drawable.menu_item_background_ice_blue);
    }
    @Override
    public void onItemClear() {
        itemView.setBackgroundResource(R.drawable.menu_item_background_white);
        int currentPosition = getLayoutPosition() + 1;
        position.setText("#" + currentPosition);
       //notifyDataSetChanged();
    }
}
BONUS QUESTION
Is there any tutorial or any info related to drag and drop between 2 RecyclerViews?
I know that there is a question on SO, but with no answer, i may be luckier here.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With