how to set itemTouchHelper swipe selectively?

2.7k views Asked by At

so i have implemented this itemtouchhelper.simple callback on a recyclerview rv.

now in this rv i have set 2 kinds on layout as a row depending on the content type.

so as i set this touchhelper on the rv it is being implemented on both of these layouts even though i did'nt want to do that.i only want to apply that swipe to only one type of this layout.

ItemTouchHelper.SimpleCallback ith = new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.RIGHT) {
        @Override
        public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
            return false;
        }

        @Override
        public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
            if(viewHolder.itemView.findViewById(R.id.messageholder_from) != null)
            {
                Log.d("texts", "onSwiped: "+viewHolder.itemView.findViewById(R.id.messageholder_from).findViewById(R.id.crfrom));
            }
            adapter.notifyDataSetChanged();
        }
    };
    new ItemTouchHelper(ith).attachToRecyclerView(rv);

as you can see this code i only want to implement the swipe on the row which has this messageholder_from child in it otherwise i don't want to implement the swipe.

is there any way to remove the swipe animation and the listener on this other child messageholder_to.

my app shows either a to_layout or a from_layout depending on he message id.

thanks for any kind of help.

2

There are 2 answers

0
Ben P. On BEST ANSWER

Inside your ItemTouchHelper.SimpleCallback, override the getSwipeDirs() method and return 0 for any row that you want to disable swiping on.

@Override
public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    if (viewHolder.itemView.findViewById(R.id.messageholder_from) == null) {
        return 0;
    }

    return super.getSwipeDirs(recyclerView, viewHolder);
}

Depending on exactly how your app is set up, there might be a better way to detect that viewHolder is the kind you want to disallow swiping on. For example, maybe you could have

if (viewHolder instanceof WrongKindOfViewHolder)

or

if (viewHolder.isNotSwipeable)
0
Abu Yousuf On

int makeMovementFlags (int dragFlags,int swipeFlags) is responsible for each row move, swipe or drag.

From documentation :

Convenience method to create movement flags.

For instance, if you want to let your items be drag & dropped vertically and swiped left to be dismissed, you can call this method with: makeMovementFlags(UP | DOWN, LEFT);

Implement getMovementFlags() method and return with makeMovementFlags(0, 0); for which row or viewholder you don't want to add swipe or drag.

Example Code:

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {

    int dragFlags = 0;
    int swipeFlags = 0;

    if (recyclerView.getLayoutManager().getClass() == LinearLayoutManager.class ) {

        LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
        int orientation = linearLayoutManager.getOrientation();

        if (orientation == LinearLayoutManager.VERTICAL) {

            swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
            dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;


        }else {
            // horizontal
            dragFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
            // no swipe for horizontal layout
            swipeFlags = 0;
        }

    }

    if (viewHolder.getAdapterPosition() == 3) {
         // disable swipe feature for position 3 
        return makeMovementFlags(0, 0);
    }


    return makeMovementFlags(dragFlags, swipeFlags);
}