KOTLIN-Create a Recycler View with Click and Long Click Listener(the right way)

KOTLIN-Create a Recycler View with Click and Long Click Listener(the right way)

In this project I will be explaining how to make a recycler view adapter, with click and long click listener. But before we start, create a project and name it RecyclerExample or anything you want. We will be using kotlin as our language of choice, you can also use java if you are familiar with the concept. When you are finished creating your project, you should have a MainActivity.kt file and an activity_main.xml as a layout file.

⚪Step1

The next thing to do is create a data class and name it “DataClass”, I know the name is self explanatory. In the parameters of the data class we created, add a “title” of String type and "detail" of String type, Your data class should look something like this.

data class DataClass(val title: String, val detail: String)

⚪Step2

Next create a layout file and call it “recycler_item”, this will be the layout that will display each of data that will display in the recycler view. Your recycler_item.xml file should look something like this.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/id_linear_layout"
    android:layout_marginVertical="3dp"
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        android:id="@+id/id_tv_title"
        android:paddingHorizontal="10dp"
        android:textStyle="bold"
        android:textColor="@color/black"
        android:textSize="30sp"
        android:gravity="center_horizontal"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        android:id="@+id/id_tv_detail"
        android:paddingHorizontal="10dp"
        android:textStyle="italic"
        android:textSize="25sp"
        android:gravity="center_horizontal"/>
</LinearLayout>

⚪Step3

Before we start creating the recycler adapter, add a recycler view to the “activity_main.xml” You will notice that we set the listitem to the recycler_item layout we created earlier, and it should look something like this.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/id_rv_recycler"
        tools:listitem="@layout/recycler_item"/>

</LinearLayout>

⚪Step4

In your MainActivity we will initialize the recycler view we created in activity_main.xml layout. To do so create a global variable named id_rv_recycler like this

// make it a global variable
private lateinit var id_rv_recycler: RecyclerView
// and then we initialize it inside the onCreate(if you are in an activity) or //onCreateView Method(if you are in a fragment)
id_rv_recycler = findViewById(R.id.id_rv_recycler)

⚪Step5

CREATING THE ADAPTER

I am going to break this step5 into section because it is quiet long and maybe it will help you understand it better.

Section1

Now lets create a recycler adapter, this is where the magic will happen. To do so create a new class (create a new class in a new file) and name it “RecyclerAdapter” (the file name should also be named RecyclerAdapter). Add this piece of code to the RecyclerAdapter class you created and it should look like this

class RecyclerAdapter: RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
    private var array_list: ArrayList<DataClass> = ArrayList()
    private var context: Context
    private var layout: Int = 0
    private var recycler_view: RecyclerView
    private lateinit var click_listener:OnItemClickListener

    constructor(context:Context,
                recyclerview: RecyclerView,
                layout:Int,
                layout_manager: RecyclerView.LayoutManager
    ){
        this.recycler_view = recyclerview
        this.context = context
        this.layout = layout
        this.recycler_view.layoutManager = layout_manager
        this.recycler_view.adapter = this
    }


    interface OnItemClickListener{
        // inter face for auto loading itemClick and longItemClick
        fun onItemClick(position: Int, view:View)
        fun onLongItemClick(position: Int, view:View)
    }

   override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(context).inflate(layout, parent, false)
        return ViewHolder(view, click_listener)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // bind your view holder class with your recycler adapter
        // you are binding your cell view with your recyclerview
        val arraylist = array_list[position]
        holder.title.text = arraylist.title
        holder.detail.text = arraylist.detail
    }

    override fun getItemCount(): Int {
        //get the number of item in your recyclerview
        return array_list.size
    }

    fun emptyAdapter(){
        //remove all item from your recyclerview
        array_list.clear()
    }

    fun addToAdapter(element: DataClass){
        // add item to your recyclerview
        array_list.add(element)
    }

    fun addToAdapter(index:Int, element:DataClass){
        // add item to an index spot of your recyclerview
        array_list.add(index, element)
    }


    class ViewHolder(item_view: View, listener:OnItemClickListener): RecyclerView.ViewHolder(item_view) {
        // initialize the item your view holder will hold
        val title: TextView = item_view.findViewById(R.id.id_tv_title)
        val detail: TextView = item_view.findViewById(R.id.id_tv_detail)
        init {
            item_view.setOnLongClickListener{
                listener.onLongItemClick(adapterPosition, item_view)
                true
            }
            item_view.setOnClickListener {
                listener.onItemClick(adapterPosition, item_view)
            }
        }
    }
}

Section2

You will notice the “RecyclerAdapter” extends “RecyclerView.Adapter” and has a type of “RecyclerAdapter.ViewHolder”. The RecyclerAdapter.ViewHolder is the inner class we created inside RecyclerAdapter, which we called ViewHolder. This two class work side by side in making the recycling magic happen.

Section3

We also created private global variables that can be access from anywhere inside the RecyclerAdapter class. Notice the array_list variable is an ArrayList type that accept the class DataClass we created earlier as it’s type.

Section4

We created an interface named “OnItemClickListener ”that will be use to load the click and long click listener (the interface can be named anything), we also gave the interface two default method named onItemClick and onLongItemClick, they both accept a position of type Int and a view of type View.

Section5

We also created a constructor that accepts the application context, recycler view, layout (which is the resource directory of the recycler_item.xml file), and the layout manager (which will help us manage the way our recycler items will be display). Then we initialize the global variables we created earlier inside the constructor.

Section6

We also override the default method that came with the extended "RecyclerView.Adapter". which are onCreateViewHolder, onBindViewHolder and getItemCount .

The emptyAdapter, addToAdapter, are method we created on our own to help us manage the array_list.

Section7

We also created an class named “ViewHolder” inside the RecyclerAdapter class, which has parameter item_view of type View (this is very nesecceray) and the listener of type OnItemClickListener which is the interface we created in the top class. The ViewHolder extends the “RecyclerView.ViewHolder” and takes item_view as the parameter. Inside the Viewholder, we initialize the views we created inside the “recycler_item.xml” layout file.

Section8

We set an init execution that will execute anytime the ViewHolder is been called by the RecyclerAdapter. The adapterPosition we pass inside the “listener.onLongItemClick(adapterPosition, item_view)” and the “listener.onItemClick(adapterPosition, item_view)” holds the position of each item view in the adapter, and this adapterPosition came with the extended RecyclerView.ViewHolder.

WOW! I hope you understand all that, if you don’t I will paste the link to my git repository where you will see the the full code.

Section9

Now lets continue. Create a method inside the “RecyclerAdapter class not the ViewHolder class” and name it onClickListener, your method should look something like this.

fun onClickListener(listener:OnItemClickListener){
    click_listener = listener
}

This will give you the edge of been able to call this function from your activity or fragment class

⚪Step6

HOW TO USE THIS ADAPTER

Section1

We are done with the RecyclerAdapter class, now open your MainActivity.kt file then make the RecyclerAdapter class globally callable like this

private lateinit var rv_adapter: RecyclerAdapter

and initialize the rv_adapter inside the onCreate(if you are in an activity) or onCreateView(if you are in a fragment) method like this. If you are in a fragment you can change the “applicationContext” to “requireContext()”

rv_adapter = RecyclerAdapter(applicationContext,
    id_rv_recycler,
    R.layout.recycler_item,
    LinearLayoutManager(applicationContext, RecyclerView.VERTICAL, false)
)

Section2

First let’s add some dummy data to the recycler adapter so it display in the recycler view

rv_adapter.addToAdapter(DataClass("Jumanji", "Welcome to the jungle"))
rv_adapter.addToAdapter(DataClass("Venom", "Let there be carnage"))
rv_adapter.addToAdapter(DataClass("The Witcher", "Nightmare of the wolf"))
rv_adapter.addToAdapter(DataClass("Teen Titans", "Go to the movies"))

This is how you use the adapter onItemClickListener and onItemLongClickListener, the “position” is each position of the row and the “view” is each row in the RecyclerView

rv_adapter.onClickListener(
    object : RecyclerAdapter.OnItemClickListener {
        override fun onItemClick(position: Int, view: View) {
            // click execution goes here
            Toast.makeText(applicationContext, "position $position was clicked", Toast.LENGTH_SHORT).show()
        }
        override fun onLongItemClick(position: Int, view: View) {
            // long click execution goes here
            Toast.makeText(applicationContext, "position $position was long  clicked", Toast.LENGTH_SHORT).show()
        }
    }
)

1_wUzWG_q0ddKcDGg50FxBYQ.png 1__Vq14k9Mrb0ryfeI7r8Umw.png 1_Gjt1xcb8Lt0aH1H5JFyhqQ.png SUMMARY

If you have any question or you code is not working well you can check my git repository for clues or solutions or you can leave me a comment. https://github.com/Ohior