---
title: "A Better Way to Handle Click Action in a RecyclerVIew Item."
description: "There are various approaches to set the OnClickListener to a RecyclerView item. Here is one of the approaches that I consider to be the best practice."
canonical: https://oozou.com/blog/a-better-way-to-handle-click-action-in-a-recyclerview-item-60
locale: en
date: 2020-06-30
author: "OOZOU Team"
---

# A Better Way to Handle Click Action in a RecyclerVIew Item.

> There are various approaches to set the OnClickListener to a RecyclerView item. Here is one of the approaches that I consider to be the best practice.

Published: 2020-06-30 · Author: OOZOU Team (Engineering) · 3 min read

Setting the **OnClickListener** on the list item is a very common task in Android development. As an Android developer, you should be well-familiar with it. However, I have seen various implementations from different developers. Back in the day when I still used Java, I would need an interface that specified the click listener’s behavior to handle the click action in the **Fragment** or **Activity** with the data from a specific item of the **RecyclerView**. The interface might look like this:

```java
public interface OnItemClickListener {
    void onItemClick(Model model);
}
```

Now in 2020, we have Kotlin and we can just use **Lambda** to achieve the same behavior as having the interface class in Java.
Let's begin with the **RecyclerAdapter**. In our Recycler Adapter, the constructor takes a **Lambda** as the constructor param. This **Lambda** acts as the listener with the model to be rendered in our **Fragment/Activity.**

```kotlin
class AwesomeAdapter(
    private val onItemClicked: (Model) -> Unit
) : RecyclerView.Adapter<ViewHolder> {

    var data: List<Model> = ArrayList(0)
         set(value) {
             field = value
             notifyDataSetChanged()
         }
}
```

Here comes the part where I have seen people implement it differently. Where do you think we should set the click listener to each item of the RecyclerView; **onBindViewHolder** or **onCreateViewHolder**?
Setting the click listener in **onBindViewHolder** is easy because the adapter is holding the list and we can access **data** items by their position in **onBindViewHolder** directly:

```kotlin
override fun onBindViewHolder(
        holder: ViewHolder,
        position: Int
    ) {
        val item = data[position]
        holder.bind(item)
        holder.itemView.setOnClickListener { onItemClicked(item) }
    }
}
```

However, in RecyclerView the **onBindViewHolder** gets called **every time** the ViewHolder is bound and the **setOnClickListener** will be triggered too. Therefore, setting a click listener in **onCreateViewHolder** which invokes only when a ViewHolder gets created is preferable**.**Here is a diagram of the implementation.

In the Adapter class, **onCreateViewHolder** has no reference to the position, so we need to refer to RecyclerView item's position by the **adapterPosition** field in **ViewHolder** class. As you can see, we pass another Lambda into the ViewHolder class so that we can refer to an adapter position data in the Adapter class.

# On Fragment/Activity

This is how we initialize the adapter with a click listener.

```kotlin
val adapter = AlbumAdapter {model -> 
   //The click action you want to perform.
}
```

# On Adapter class

```kotlin
class ArtistAdapter(
    private val onItemClicked: (Model) -> Unit
) : RecyclerView.Adapter<ArtistViewHolder>() {

    var data: List<Model> = ArrayList(0)
        set(value) {
            field = value
            notifyDataSetChanged()
        }

    override fun onCreateViewHolder(parent: ViewGroup, type: Int): ArtistViewHolder {
        val viewHolder = LayoutInflater.from(parent.context).inflate(R.layout.viewholder_awesome, parent, false)
        return AwesomeViewHolder(viewHolder) {
            onItemClick(values[it])
        }
    }

    override fun getItemCount(): Int = data.size

    override fun onBindViewHolder(viewHolder: ArtistViewHolder, position: Int) {
        viewHolder.bind(data[position])
    }

}
```

**ViewHolder Class**

```kotlin
class ArtistViewHolder(
    view: View,
    onItemClicked: (Int) -> Unit
) : RecyclerView.ViewHolder(view) {
    init {
        itemView.setOnClickListener {
            onItemClicked(adapterPosition)
        }
    }

    fun bind(model: Model) {
        //bind data
    }
}
```

# Conclusion
I think setting a click listener of the RecyclerView item in **onCreateViewHolder** is a best practice since it reduces the function call significantly compared to doing it in **onBindViewHolder**. However, you might wonder if it is really necessary because setting a click listener is just a small operation and won't cause much of the performance issue anyway. That is true, but let's consider the situation where each item of the RecyclerView is getting more complex like having multiple click actions or even including a long click event. In this case, implementing the approach, I mentioned in this article would be more preferable.
And that is it! Thank you for reading.

# Source
\- cover image: https://www.goodfon.com/wallpaper/chernyi-fon-ruki-soprikasaiutsia.html

---

Contact OOZOU: hello@oozou.com · +66 2544 0000 · https://oozou.com/contact

More for AI agents: https://oozou.com/llms.txt · every page has a markdown twin at its URL plus ".md"
