1

I want to swipe and drag & drop items in RecyclerView using ItemTouchHelper class. The RecyclerView is placed inside BottomSheetDialog.

Following is the code for setting up RecyclerView

musicAdapterRecyclerView = new MusicAdapterRecyclerView(this, mainList);
    playlistRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    playlistRecyclerView.setClickable(true);
    playlistRecyclerView.setHasFixedSize(false);
    playlistRecyclerView.setAdapter(musicAdapterRecyclerView);
    bottomSheetDialog.setContentView(view);
    bottomSheetDialog.setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialogInterface) {
            BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialogInterface;
            FrameLayout bottomSheet = (FrameLayout) bottomSheetDialog
                    .findViewById(android.support.design.R.id.design_bottom_sheet);
            BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_COLLAPSED);
        }
    });
    playlistRecyclerView.scrollToPosition(playingIndex);
    playlistRecyclerView.setNestedScrollingEnabled(false);
    setupItemTouchHelper();

Following is the code to setup ItemTouchHelper class on RecyclerView

 public void setupItemTouchHelper(){
    final ItemTouchHelper.Callback callback = new ItemTouchHelper.Callback() {
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            adapterRecyclerView =(MusicAdapterRecyclerView) recyclerView.getAdapter();

            int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
            int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
            return makeMovementFlags(dragFlags, swipeFlags);
        }



        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            int fromPosition = viewHolder.getAdapterPosition();
            int toPosition = target.getAdapterPosition();
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(mainList, i, i + 1);
                }
            } else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(mainList, i, i - 1);
                }
            }
            musicAdapterRecyclerView.notifyItemMoved(fromPosition, toPosition);
            return true;

        }

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

            final int pos = viewHolder.getAdapterPosition();
            if(pos<0 && pos>=mainList.size()){
                return;
            }

            mainList.remove(pos);
            adapterRecyclerView.removeItem(pos);
            adapterRecyclerView.notifyItemRemoved(pos);
            adapterRecyclerView.notifyItemRangeChanged(pos,mainList.size());

        }




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

        @Override
        public boolean isItemViewSwipeEnabled() {
            return true;
        }
    };
    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
    itemTouchHelper.attachToRecyclerView(playlistRecyclerView);

}

Problem

  1. When user swipes item on recyclerView, mainList is updated, swipe animation works properly, but RecyclerView is not updated unless it is scrolled.

  2. OnMove() method of ItemTouchHelper used for drag and drop (rearranging items) not being called.

Sarthak Aggarwal
  • 2,284
  • 1
  • 8
  • 12

0 Answers0