Montoya
Montoya

Reputation: 3049

Android - Swipe to delete RecyclerView

I am trying to implement swipe to delete the same as Gmail app "Swipe to archive":

gmail swipe delete gmail swipe delete

I have tried many tutorials but none of them works as fast as gmail, I prefer to not work on external library. How can i do it?

Edit:

My code so far-

  ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
                public boolean onMove(RecyclerView recyclerView,
                                               RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//                    final int fromPos = viewHolder.getAdapterPosition();
//                    final int toPos = viewHolder.getAdapterPosition();
//                    // move item in `fromPos` to `toPos` in adapter.
                    return true;// true if moved, false otherwise
                }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
                //Remove swiped item from list and notify the RecyclerView
                mAdapter.notifyItemRemoved(viewHolder.getLayoutPosition());
            }
        };
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
        itemTouchHelper.attachToRecyclerView(mRecyclerView);

I've managed to enable swipe gesture but i don't know how to add a background and an image under the viewHolder. I tried to put another FrameLayout at the item_XXX.xml file but on swipe it throws the whole item with the background.

Upvotes: 78

Views: 94925

Answers (4)

JohnnyLambada
JohnnyLambada

Reputation: 12826

Here's the minimum code in your onCreate that sets up "Swipe Left to Delete":

binding.rows.adapter = adapter
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
    override fun onMove(v: RecyclerView, h: RecyclerView.ViewHolder, t: RecyclerView.ViewHolder) = false
    override fun onSwiped(h: RecyclerView.ViewHolder, dir: Int) = adapter.removeAt(h.adapterPosition)
}).attachToRecyclerView(binding.rows)

This assumes your Adapter class has a removeAt function. Mine looks like this:

fun removeAt(index: Int) {
    items.removeAt(index)   // items is a MutableList
    notifyItemRemoved(index)
}

Thanks @RahulRaina for your Java answer!

Upvotes: 8

Tsur Yohananov
Tsur Yohananov

Reputation: 53

You can try Swipeable-RecyclerView

    SwipeableRecyclerView rv = findViewById(R.id.rv);
    rv.setLayoutManager(new LinearLayoutManager(this));
    rv.setAdapter(mAdapter);

    rv.setListener(new SwipeLeftRightCallback.Listener() {
        @Override
        public void onSwipedLeft(int position) {
            mList.remove(position);
            mAdapter.notifyDataSetChanged();
        }

        @Override
        public void onSwipedRight(int position) {
            mList.remove(position);
            mAdapter.notifyDataSetChanged();
        }
    });

xml for two sides swipe

<com.tsuryo.swipeablerv.SwipeableRecyclerView
    android:id="@+id/rv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:leftBgColor="@color/colorAccent"
    app:leftImage="@drawable/ic_remove"
    app:leftText="Delete"
    app:rightBgColor="@color/blue"
    app:rightImage="@drawable/ic_check"
    app:rightText="Read"
    app:textColor="@android:color/white"
    app:textSize="20sp" />

Upvotes: 2

Nemanja Kovacevic
Nemanja Kovacevic

Reputation: 3560

I had to do this the other day and I had some issues so I decided to write a blog post on it. No 3rd party lib necessary.

Basically, you wouldn't draw the "undo state" via onChildDraw, it would be done via ViewHolder. Also you wouldn't actually delete row in onSwipe just mark it as "pending delete" and notify adapter to rebind it in "undo state". At the same time you post a Runnable actually removing the row in x seconds unless undo button is pressed...

Upvotes: 32

Rahul Raina
Rahul Raina

Reputation: 3450

Simple Code for RecyclerView Swipe:

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

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                Toast.makeText(ListActivity.this, "on Move", Toast.LENGTH_SHORT).show();
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
                Toast.makeText(ListActivity.this, "on Swiped ", Toast.LENGTH_SHORT).show();
                //Remove swiped item from list and notify the RecyclerView
                int position = viewHolder.getAdapterPosition();
                arrayList.remove(position);
                adapter.notifyDataSetChanged();

            }
     };

Then set callback for recyclerView with below statements:

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
 itemTouchHelper.attachToRecyclerView(rv);

Upvotes: 77

Related Questions