Avin's Blog

How to add onClick to RecyclerView list items in Kotlin

April 22, 2021
Tags: Android, Android Basics, Github Repository App, RecyclerView, Kotlin,

If you are here chances are you already know how to create a RecyclerView, if not take a look at How to create a RecyclerView with custom Adapter in Kotlin.

Overview

Kotlin has higher order functions, which are functions that can have functions as parameters or return functions. So the idea here is that

  1. Create a function onListItemClick that handles the click event in the UI(Activity/Fragment). The reason you want to create a function here is because list item clicks usually result in UI changes like moving to a different Activity/Fragment, show a Toast/Snackbar, etc.
  2. Pass this function as argument to the adapter followed by passing the function again to the ViewHolder while creating them.
  3. In the ViewHolder make the ViewHolder class implement View.OnClickListener followed by implementing the required onClick method. In the onClick method call the onListItemClick function.

Now when a list item is clicked, the ViewHolder handles the click and calls the method defined in our Activity/Fragment.

As an example I will be adding onClick to RecyclerView in a simple app that displays a list of Github repositories.

Step 1: Create a function that handles click in the UI

Here I am just displaying a Toast, you may navigate to another Activity or Fragment.

class MainActivity : AppCompatActivity(){
    ...
    ...

    // In MainActivity.kt
    private fun onListItemClick(position: Int) {
        Toast.makeText(this, mRepos[position].name, Toast.LENGTH_SHORT).show()
    }
}

Step 2: Add a new function as argument to the Adapter

Change signature of the Adapter so that it accepts a function as an argument.

class GithubRepositoryAdapter(private val onItemClicked: (position: Int) -> Unit) : RecyclerView.Adapter<RepositoryViewHolder>() {
    private val TAG = javaClass.simpleName
    private var mAllRepositories: Array<GithubRepository>? = null


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RepositoryViewHolder {
        val context = parent.context
        val inflater = LayoutInflater.from(context)
        val view = inflater.inflate(R.layout.repository_list_item, parent, false)
        return RepositoryViewHolder(view, onItemClicked)
    }

Now make sure to pass onListItemClick to the adapter in the UI.

class MainActivity : AppCompatActivity() {
    ...
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        ...
        mRepositoryRecyclerView = findViewById(R.id.rv_repo_list)

        mGithubRepositoryAdapter = GithubRepositoryAdapter{ position -> onListItemClick(position) }
        mRepositoryRecyclerView.adapter = mGithubRepositoryAdapter
    }
}

Step 3: Add a new function as argument to the ViewHolder

Similarly change the ViewHolder parameter and accept a function. Also implement View.onClickListener and implement the onClick method. Finally call the function inside it like so:

class RepositoryViewHolder(
        itemView: View, 
        private val onItemClicked: (position: Int) -> Unit
) : RecyclerView.ViewHolder(itemView), View.OnClickListener {

    ...
    ...

    init {
        itemView.setOnClickListener(this)
    }

    ...
    ...

    override fun onClick(v: View) {
        val position = adapterPosition
        onItemClicked(position)
    }
}

Hopefully you feel more comfortable with adding onClick to RecyclerViews. If you find any errors, have feedback or just want to say hi please don’t hesitate to leave a comment below.