Android RecycleView Swipe to dismiss and Item sorter using ItemTouchHelper and ItemTouchHelper.SimpleCallback

In this tutorial, we are going to learn how to implement android RecycleView swipe to dismiss and item sorter.

Since this tutorial will make use of a RecycleView with corresponding RecycleView adapter, we are going to reuse the code we used to create a full functional RecycleView tutorial.

So in order to following this tutorial, I will suggest that you first read – How to highlight RecycleView Item Row Background in Android – tutorial because we are going to copy almost all the code for populating a RecycleView.

To add android Swipe to dismiss or RecycleView item sorter, we are going to make use of the ItemTouchHelper and the default SimpleCallback class.

The OnSwipe and onMove methods of this class will be override.

Lets start to soil our hands in code. we will create our project in our IDE. For this tutorial, I am using the following tools and environment, feel free to use what works for you.

Windows 7

Android Studio

Sony Xperia ZL

Min SDK 14

Target SDK 23

To create a new android application project, follow the steps as stipulated below.

Go to File menu

Click on New menu

Click on Android Application

Enter Project name: AndroidSwipeToDismiss

Package: com.inducesmile.androidswipetodismiss

Select Blank Activity

Keep other default selections

Continue to click on next button until Finish button is active, then click on Finish Button.

We are going to add the RecycleView widget to our project. Open your app build.gradle file located at Gradle Script folder, copy and paste this line of code. You will see a link with Sync Now. Click on Sync Now to add this library to your project.

compile 'com.android.support:recyclerview-v7:23.1.1'

Now, lets go to our application main layout file which will contain the RecycleView widget. Open the layout file activity_main.xml located at res > layout folder. Copy and paste the code below inside the layout file.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.inducesmile.androidrecycleviewbackgroundselect.MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:scrollbars="none" />
</RelativeLayout>

We will move on to create the item list layout which our adapter will inflate. Right click on the layout folder and choose XML > Layout XML file. Name the file list_item.xml. Open this file and add the following code snippet in it.

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">
    <TextView
        android:id="@+id/song_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:layout_marginTop="10dp"
        android:textSize="18dp"
        android:textStyle="bold"
        android:textColor="@color/colorPrimaryDark"/>
    <TextView
        android:id="@+id/song_year"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:textColor="#000"
        android:layout_below="@+id/song_title"
        android:layout_alignLeft="@+id/song_title"
        android:layout_alignStart="@+id/song_title"
        android:layout_marginTop="20dp" />
    <TextView
        android:id="@+id/song_author"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Text"
        android:textColor="#000"
        android:layout_alignTop="@+id/song_year"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>

We will create the RecycleView Adapter which will bind our data source to our application list items of the RecycleView.

Right click on the package folder located at java > package folder, click on New and select Java file. Name the file RecyclerViewAdapter.java.

This adapter class will extends RecyclerView.Adapter<RecyclerViewHolders>. Open this file, copy and paste the code below to the file.

RecyclerViewAdapter.java

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders>{
    private List<ItemObject> itemList;
    private Context context;
    public RecyclerViewAdapter(Context context, List<ItemObject> itemList) {
        this.itemList = itemList;
        this.context = context;
    }
    @Override
    public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
        RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
        return rcv;
    }
    @Override
    public void onBindViewHolder(RecyclerViewHolders holder, int position) {
        holder.songTitle.setText("Song Title: " + itemList.get(position).getSongTitle());
        holder.songYear.setText("Song Year: " + itemList.get(position).getSongYear());
        holder.songAuthor.setText("Song Author: " + itemList.get(position).getSongAuthor());
    }
    @Override
    public int getItemCount() {
        return this.itemList.size();
    }
}

We are also going to create a ViewHolder class. You can see that the Adapter class makes use of the ViewHolder pattern.

Follow the steps we used to create the previous java file but in this case we will name our java file RecyclerViewHolders.java.

Open this class, copy and paste the code below inside this file.

RecyclerViewHolders.java

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
    public TextView songTitle;
    public TextView songYear;
    public TextView songAuthor;

    public RecyclerViewHolders(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        songTitle = (TextView)itemView.findViewById(R.id.song_title);
        songYear = (TextView)itemView.findViewById(R.id.song_year);
        songAuthor = (TextView)itemView.findViewById(R.id.song_author);
    }
    @Override
    public void onClick(View view) {
        
    }
}

Create an Entity object which will hold the data we will use to bind the widgets in the RecycleView item rows. The class has three string variables, a constructor that accepts the three parameters and getter methods from individual variables.

Follow the same steps above to create a new java file. We will name the file ItemObject.java. Once you have created this file, open the file, copy and paste the code below inside the file.

ItemObject.java

public class ItemObject {
    private String songTitle;
    private String songYear;
    private String songAuthor;
    public ItemObject(String songTitle, String songYear, String songAuthor) {
        this.songTitle = songTitle;
        this.songYear = songYear;
        this.songAuthor = songAuthor;
    }
    public String getSongTitle() {
        return songTitle;
    }
    public String getSongYear() {
        return songYear;
    }
    public String getSongAuthor() {
        return songAuthor;
    }
}

To bring this all together, we will move to the MainActivity file. In this class, we will get an instance of the RecycleView, then, we will create an object of the Adapter and pass it as a parameter to the setAdapter method of the RecycleView class.

We have created a returnListItems() method which return a List object that stores the ItemObject that serves as the data source.

Open the MainActivity.java file, copy and paste the following code inside the class.

MainActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private final String TAG = "MainActivity";
    private RecyclerView recyclerView;
    private LinearLayoutManager layoutManager;
    private RecyclerViewAdapter adapter;

    private ItemTouchHelper itemTouchHelper;
    private List<ItemObject> posts;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallbackItemTouchHelper);

        recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
        recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
        layoutManager = new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(layoutManager);

        posts = returnListItems();

        adapter = new RecyclerViewAdapter(MainActivity.this, posts);
        recyclerView.setAdapter(adapter);
        itemTouchHelper.attachToRecyclerView(recyclerView);
    }

    private List<ItemObject> returnListItems(){
        List<ItemObject> items = new ArrayList<ItemObject>();
        items.add(new ItemObject("Blank Space", "Taylor Swift", "2016"));
        items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016"));
        items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016"));
        items.add(new ItemObject("Cheerleader", "OMI", "2016"));
        items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016"));
        items.add(new ItemObject("Hello", "Adele", "2016"));
        return items;
    }

    ItemTouchHelper.SimpleCallback simpleCallbackItemTouchHelper = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.RIGHT){

        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {

            final int fromPosition = viewHolder.getAdapterPosition();
            final int toPosition = target.getAdapterPosition();

            ItemObject prev = posts.remove(fromPosition);
            posts.add(toPosition > fromPosition ? toPosition - 1 : toPosition, prev);
            adapter.notifyItemMoved(fromPosition, toPosition);

            adapter.notifyItemMoved(fromPosition, toPosition);
            return true;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            int position = viewHolder.getAdapterPosition();
            posts.remove(position);
            adapter.notifyDataSetChanged();
        }
    };
}

In the class above, we created an object of the ItemTouchHelper and call its method – itemTouchHelper.attachToRecyclerView(recyclerView);  and our RecycleView instance is passed as a parameter.

Subsequently, we have created an inner class for the SimpleCallback class. The codes in the override methods onSwipe and onMove is shown above.

In this code, if you look at this line

recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));

If you look at the single line of code above, we are using it to add a line separator for the items in the RecycleView.

If you like you can omit this part but if you want to add a line separator to the items of the RecycleView, then create a new java file and name it SimpleDividerItemDecoration.java.

Open the file, copy and paste the following code inside this file

SimpleDividerItemDecoration.java

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
    private Drawable mDivider;
    public SimpleDividerItemDecoration(Context context) {
        mDivider = ContextCompat.getDrawable(context, R.drawable.line_divider);
    }
    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
}

Also, we will add this drawable layout file in the drawable folder. Create a new Drawable layout file inside the Drawable folder and name it line_divider.xml. Copy and paste the following code inside the file.

line_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size
        android:width="1dp"
        android:height="1dp" />
    <solid android:color="@color/colorDivide" />
</shape>

Run your application and see for yourself what we have just created.

This brings us to the end of this tutorial, If you find anything confusing kindly contact me with your questions or use the comment box below.

You can download the code for this tutorial below. If you are having hard time downloading the tutorials, kindly contact me.

Remember to subscribe with your email address so that you will be among the first to receive my new post once it is published.

Please if you love this tutorial, kindly download my new android app – Daily Pocket Calculator – in Google Play Store and let me know what you think about it.

OTHER INTERESTING POSTS:

Add a Comment