Click Handling in Multi-View RecyclerViews
A quick glance into how to handle clicks in a Multi-View RecyclerView….the Kotlin way.
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
- Define an
OnClickListener
interface in your adapter like so:
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…
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:
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!