If you’ve used a RecyclerView, you may know that they don’t have a setOnItemClickListener as ListView had, so we have to create our own way to do it. Many people asked me how to do this, so that’s why I decided to write about it.

There are many ways to achieve this, but I will show you the way I usually do it. My mechanism consists of passing the listener as a parameter to the constructor and then assign it when I bind the data to the view in onBindViewHolder .

In Java, you would need an interface that specifies listener’s behaviour. In this example, there is a sample model called ContentItem , so the click will return an item of that type:

public interface OnItemClickListener { void onItemClick(ContentItem item); }

In Kotlin you don’t need this. You can’t just use a lambda to get the same result. We’ll see it in a minute

If you haven’t, I encourage you to learn Kotlin, because nowadays is the present of Android! Android is Kotlin first. I recommend you to join my free masterclass so that you can easily start with it.

The constructor will receive a lambda that represents the listener, along with the items to be rendered:

class ContentAdapter( private val items: List<ContentItem>, private val listener: (ContentItem) -> Unit ) : RecyclerView.Adapter<ViewHolder>

You could alternatively create a setOnItemClickListener method and assign it that way. Now, in onBindViewHolder the view is assigned with this click listener:

override fun onBindViewHolder(holder: ViewHolder, position: Int) { val item = items[position] holder.bind(item) holder.itemView.setOnClickListener { listener(item) } }

Use it whenever you need it by creating a new adapter and the listener that will implement the behaviour when an item is clicked. A simple example:

Want to learn Kotlin? Check my free guide to create your first project in 15 minutes! GET THE FREE GUIDE

recycler.adapter = ContentAdapter(items) { item -> toast(item.title) };

If you want to know how this toast extension function is created, go check out my article about extension functions in Kotlin.

Take a look at the whole code of this adapter. Of course there are many alternatives here. In the end, the implementation is left to the developer when using RecyclerView , so choose whatever fits better in your situation.

class ContentItem(val name: String, val imageUrl: String) class ContentAdapter( private val items: List<ContentItem>, private val listener: (ContentItem) -> Unit ) : RecyclerView.Adapter<ContentAdapter.ViewHolder>() { override fun onCreateViewHolder( parent: ViewGroup, viewType: Int ): ViewHolder { val v = parent.inflate(R.layout.view_item) return ViewHolder(v) } override fun onBindViewHolder( holder: ViewHolder, position: Int ) { val item = items[position] holder.bind(item) holder.itemView.setOnClickListener { listener(item) } } override fun getItemCount(): Int { return items.size } class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { private val name = itemView.findViewById<TextView>(R.id.name) private val image = itemView.findViewById<ImageView>(R.id.image) fun bind(item: ContentItem) { name.text = item.name image.loadUrl(item.imageUrl) } } }

Like this: Like Loading...