Android RecyclerView Swipe To Delete Example Button And Undo

android listview swipe to delete, android recyclerview swipe to delete, android expandablelistview checkbox, android tutorial, kotlin video slider

Android RecyclerView Swipe To Delete Example Tutorial is explained here.

We will make a recyclerview such that user swipe to show button, which will delete the row.

Android RecyclerView Swipe to delete example is similar like gmail app.

We will also implement an UNDO feature, which will restore the deleted row item.

Also Read,

First, check the output of the example, then we will create it with android studio.

Step 1. Create a new project.

Always try to create new project with empty activity in android studio.

Step 2. Make row item layout

Prepare new layout resource file named rv_item.xml

Copy following source code in it

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="5dp"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    tools:context=".MainActivity"
    tools:ignore="NamespaceTypo">

    <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:layout_gravity="center"
        app:cardBackgroundColor="#ffffff"
        android:layout_marginTop="0dp"
        card_view:cardCornerRadius="1dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/tv"
                android:height="90dp"
                android:gravity="center"
                android:paddingLeft="10dp"
                android:text="Image"
                android:textColor="#000"
                android:textStyle="bold"
                android:textSize="18sp" />

        </LinearLayout>

    </android.support.v7.widget.CardView>
</RelativeLayout>

This layout file rv_item.xml file represents the layout for each row of recyclerview.

Here, we will create simple row item with just one text in it.

TextView is added to show the name of the row item.

Step 3. Update gradle file

Add below lines in your build.module(Module:app) file

 compile 'com.android.support:recyclerview-v7:27.1.1'
 compile 'com.android.support:cardview-v7:27.1.1'
 compile 'com.android.support:design:27.1.1'

Above three lines add the required classes for recyclerview, cardview and material design respectively.

Step 4. Making Model Class

Make a new JAVA class and give it a name Model.java

Add below code in it

/**
 * Created by Parsania Hardik on 28-Jun-17.
 */
public class Model {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


}

Model class is something like a data transporter for recyclerview.

An object of model class is created for each row item of recyclerview then, all these objects are stored in an ArrayList.

Finally, ArayList will populate the recyclerview in Adapter class.

Step 5. Creating Adapter

A java class named Adapter.java will contain below source code. Go ahead and make new java class.

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;

/**
 * Created by Parsania Hardik on 26-Jun-17.
 */
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {

    private LayoutInflater inflater;
    private ArrayList<Model> imageModelArrayList;


    public Adapter(Context ctx, ArrayList<Model> imageModelArrayList){

        inflater = LayoutInflater.from(ctx);
        this.imageModelArrayList = imageModelArrayList;
    }

    public void removeItem(int position) {
        imageModelArrayList.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, imageModelArrayList.size());
    }
    public void restoreItem(Model model, int position) {
        imageModelArrayList.add(position, model);
        // notify item added by position
        notifyItemInserted(position);
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = inflater.inflate(R.layout.rv_item, parent, false);
        MyViewHolder holder = new MyViewHolder(view);

        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        holder.time.setText(imageModelArrayList.get(position).getName());
    }

    @Override
    public int getItemCount() {
        return imageModelArrayList.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder{

        TextView time;


        public MyViewHolder(View itemView) {
            super(itemView);

           time = (TextView) itemView.findViewById(R.id.tv);

        }

    }
}

Adapter will populate the RecyclerView with the help of ArrayList of Model objets.

Two methods of adapter are important here.

Understanding removeItem()

This method will remove the row item when user swipes left or right.

Look at below code

public void removeItem(int position) {
        imageModelArrayList.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, imageModelArrayList.size());
}

When user swipes left or right, this method will be called from MainActivity.java class along with the position as a parameter.

You can see in above code that an object of model class is removed from ArrayList who is present at position given by parameter.

Understanding resoreItem()

This method will restore the deleted item, when user clicks on UNDO.

Look at following code

public void restoreItem(Model model, int position) {
        imageModelArrayList.add(position, model);
        // notify item added by position
        notifyItemInserted(position);
}

When user clicks on UNDO, a model object which was deleted and a position will be passed from Main Activity.

Then, model object will be added at the required position which was also passed from Main Activity as a parameter.

Step 6. Updating MainActivity

Update activity_main.xml as below

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/linear"
    android:background="#e4e0e0"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"/>

</android.support.design.widget.CoordinatorLayout>

Update MainActivity.java class as following

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.graphics.Canvas;
import java.util.ArrayList;
import android.support.v7.widget.helper.ItemTouchHelper;

public class MainActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private ArrayList<Model> imageModelArrayList;
    private Adapter adapter;
    private Paint p = new Paint();

    private String[] myImageNameList = new String[]{"Benz", "Bike",
            "Car","Carrera"
            ,"Ferrari","Harly",
            "Lamborghini","Silver"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recycler);

        imageModelArrayList = populateList();

        adapter = new Adapter(this,imageModelArrayList);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));

        enableSwipe();
    }

    private void enableSwipe(){
        ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                int position = viewHolder.getAdapterPosition();

                if (direction == ItemTouchHelper.LEFT){
                    final Model deletedModel = imageModelArrayList.get(position);
                    final int deletedPosition = position;
                    adapter.removeItem(position);
                    // showing snack bar with Undo option
                    Snackbar snackbar = Snackbar.make(getWindow().getDecorView().getRootView(), " removed from Recyclerview!", Snackbar.LENGTH_LONG);
                    snackbar.setAction("UNDO", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            // undo is selected, restore the deleted item
                            adapter.restoreItem(deletedModel, deletedPosition);
                        }
                    });
                    snackbar.setActionTextColor(Color.YELLOW);
                    snackbar.show();
                } else {
                    final Model deletedModel = imageModelArrayList.get(position);
                    final int deletedPosition = position;
                    adapter.removeItem(position);
                    // showing snack bar with Undo option
                    Snackbar snackbar = Snackbar.make(getWindow().getDecorView().getRootView(), " removed from Recyclerview!", Snackbar.LENGTH_LONG);
                    snackbar.setAction("UNDO", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {

                            // undo is selected, restore the deleted item
                            adapter.restoreItem(deletedModel, deletedPosition);
                        }
                    });
                    snackbar.setActionTextColor(Color.YELLOW);
                    snackbar.show();
                }
            }

            @Override
            public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {

                Bitmap icon;
                if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){

                    View itemView = viewHolder.itemView;
                    float height = (float) itemView.getBottom() - (float) itemView.getTop();
                    float width = height / 3;

                    if(dX > 0){
                        p.setColor(Color.parseColor("#388E3C"));
                        RectF background = new RectF((float) itemView.getLeft(), (float) itemView.getTop(), dX,(float) itemView.getBottom());
                        c.drawRect(background,p);
                        icon = BitmapFactory.decodeResource(getResources(), R.drawable.delete);
                        RectF icon_dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop() + width,(float) itemView.getLeft()+ 2*width,(float)itemView.getBottom() - width);
                        c.drawBitmap(icon,null,icon_dest,p);
                    } else {
                        p.setColor(Color.parseColor("#D32F2F"));
                        RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(),(float) itemView.getRight(), (float) itemView.getBottom());
                        c.drawRect(background,p);
                        icon = BitmapFactory.decodeResource(getResources(), R.drawable.delete);
                        RectF icon_dest = new RectF((float) itemView.getRight() - 2*width ,(float) itemView.getTop() + width,(float) itemView.getRight() - width,(float)itemView.getBottom() - width);
                        c.drawBitmap(icon,null,icon_dest,p);
                    }
                }
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            }
        };
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
        itemTouchHelper.attachToRecyclerView(recyclerView);
    }

    private ArrayList<Model> populateList(){

        ArrayList<Model> list = new ArrayList<>();

        for(int i = 0; i < 8; i++){
            Model imageModel = new Model();
            imageModel.setName(myImageNameList[i]);
            list.add(imageModel);
        }

        return list;
    }
}

Understanding unableSwipe() method

Refer below code

 private void enableSwipe(){
        ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                int position = viewHolder.getAdapterPosition();

                if (direction == ItemTouchHelper.LEFT){
                    final Model deletedModel = imageModelArrayList.get(position);
                    final int deletedPosition = position;
                    adapter.removeItem(position);
                    // showing snack bar with Undo option
                    Snackbar snackbar = Snackbar.make(getWindow().getDecorView().getRootView(), " removed from Recyclerview!", Snackbar.LENGTH_LONG);
                    snackbar.setAction("UNDO", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            // undo is selected, restore the deleted item
                            adapter.restoreItem(deletedModel, deletedPosition);
                        }
                    });
                    snackbar.setActionTextColor(Color.YELLOW);
                    snackbar.show();
                } else {
                    final Model deletedModel = imageModelArrayList.get(position);
                    final int deletedPosition = position;
                    adapter.removeItem(position);
                    // showing snack bar with Undo option
                    Snackbar snackbar = Snackbar.make(getWindow().getDecorView().getRootView(), " removed from Recyclerview!", Snackbar.LENGTH_LONG);
                    snackbar.setAction("UNDO", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {

                            // undo is selected, restore the deleted item
                            adapter.restoreItem(deletedModel, deletedPosition);
                        }
                    });
                    snackbar.setActionTextColor(Color.YELLOW);
                    snackbar.show();
                }
            }

            @Override
            public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {

                Bitmap icon;
                if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE){

                    View itemView = viewHolder.itemView;
                    float height = (float) itemView.getBottom() - (float) itemView.getTop();
                    float width = height / 3;

                    if(dX > 0){
                        p.setColor(Color.parseColor("#388E3C"));
                        RectF background = new RectF((float) itemView.getLeft(), (float) itemView.getTop(), dX,(float) itemView.getBottom());
                        c.drawRect(background,p);
                        icon = BitmapFactory.decodeResource(getResources(), R.drawable.delete);
                        RectF icon_dest = new RectF((float) itemView.getLeft() + width ,(float) itemView.getTop() + width,(float) itemView.getLeft()+ 2*width,(float)itemView.getBottom() - width);
                        c.drawBitmap(icon,null,icon_dest,p);
                    } else {
                        p.setColor(Color.parseColor("#D32F2F"));
                        RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(),(float) itemView.getRight(), (float) itemView.getBottom());
                        c.drawRect(background,p);
                        icon = BitmapFactory.decodeResource(getResources(), R.drawable.delete);
                        RectF icon_dest = new RectF((float) itemView.getRight() - 2*width ,(float) itemView.getTop() + width,(float) itemView.getRight() - width,(float)itemView.getBottom() - width);
                        c.drawBitmap(icon,null,icon_dest,p);
                    }
                }
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            }
        };
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
        itemTouchHelper.attachToRecyclerView(recyclerView);
    }

This method will detect the swipe movement(left or right) of the user.

Then method will decide whether user have swipe left or right. Here, we are deleting row item on both swipe, but you can update them as per your requirement.

After removing the row item, a snackbar will be shown at the bottom of the screen.

This snackbar contains the UNDO button, which can be used to restore the deleted row item.

So it was all about creating Swipe to delete in recyclerview.

If you want to use third party library, then you can use below github library.

https://github.com/hudomju/android-swipe-to-dismiss-undo

But, it is better not to use third party library as it increases the apk file size.

Share our articles with other learners to help them in their journey.

Cheers and Happy coding! šŸ™‚

Download Source Code For Android RecyclerView Swipe To Delete

Click on below link to download android studio source code.

[sociallocker]RecyclerView Swipe To Delete[/sociallocker]