Click Handling in Multi-View RecyclerViews

A quick glance into how to handle clicks in a Multi-View RecyclerView….the Kotlin way.

Sean Larson
2 min readApr 14, 2019

In a previous post, we discussed implementing a Multi-View RecyclerAdapter using the visitor pattern. If you haven’t read it, check it out here.

Let’s now take a look at click-handling with a single view-type and then we’ll see how it looks in a multi-view adapter.

Before RecyclerViews were a thing, we used ListViews. ListViews had a clickListener interface that made handling clicks relatively painless. With the advent of RecyclerView, listing items becomes much more efficient and versatile. However, RecyclerViews don’t have out-of-the-box click-handling. Therefore, like so many other things in Android-land throughout the years, we have had to roll our own solution.

“Old school” click handling in Java

  1. Define an OnClickListener interface in your adapter like so:
This is a single-view example. It’s easy to imagine how quickly this can grow given multiple view types.

2. Implement the interface in an activity or fragment:

Voilá!

“Old school” click handling with Kotlin

It would be easy enough to Kotlin-ify the solution above. We can take advantage of Kotlin’s null-safety feature to rid ourselves of that nasty little null-check block. Thus, we no longer have to explicitly test for null before we use onItemClickListener.onItemClick(item); Behold…

This would be the entire adapter, minus logic for the view holder.

That’s nice, isn’t it? We have made onItemClickListener null safe with the ? operator. This makes onItemClick(items[position]) optional if onItemClickListener happens to be null. (Perhaps someone forgot to set it during development— an error which should never make it to production without someone else noticing. However, it’s nice to highlight null safety features for those learning Kotlin.)

How we do click handling better with Kotlin

Let’s talk about a different approach: one that harnesses the power of Kotlin. In Kotlin-land, functions are first-class, which means they can be variables, passed as arguments and returned from higher-order functions. This allows us to do some rather nifty things that we could never do in the past with Java. For our purposes, we are going to forget about an OnItemClickListener interface and instead, create a function called OnItemClickListener that we can pass to our adapter. When we need to use the code inside that function, we call the function and pass the required parameters in a closure. We can create this function in our activity and then pass it to the adapter in its constructor like so:

We react to the user’s click inside the onItemClickListener function by maybe replacing a fragment or starting another activity.

Now in our RecyclerView Adapter, we must setup the click handling. Notice how in the onBindViewHolder method, we call itemClickListener in holder.itemView.setOnClickListener.

Sweet! You might have already guessed how easy it will be to adapt this to a multi-view adapter. If not, have a look:

The big difference here, beyond implementing the type factory, is that we are passing the itemClickListener to the view holder to handle.

That’s it! Again, happy recycling!

--

--