Subscribe Now

* You will receive the latest news and updates on your favorite celebrities!

Trending News

Blog Post

RecyclerView Item Click: Handling single item click and long press (Kotlin)
Beginner

RecyclerView Item Click: Handling single item click and long press (Kotlin)

Today we are going to check about How to handle RecyclerView Item Click?. I am assuming that you already know how to display a list of data using RecyclerView. If you don’t know then I would suggest you check below the list of blogs first.

Prerequisite:

1. How to display a list of data into RecyclerView using LinearLayoutManager?

How to handle RecyclerView Item Click?

For handling RecyclerView Item Click in Kotlin. We can use the Higher-Order Function or Delegate Function. Let’s see one example.

  1. In your, ViewHolder Class declare one Higher-Order Function like this
    class MovieListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    
        var itemClick: ((String) -> Unit)? = null
    
    }
  2. Now invoke() this function when a user clicks on itemview. So it will behave like a sender function. Something like this
    itemView?.setOnClickListener {
    
                //invoke() function will pass the value to receiver function.
                itemClick?.invoke(movieModel.movieTitle)
            }
  3. Now on the adapter side, you just have to make one receiver code so you can consume the sent item.
    itemClick = { movieTitle ->
                    this@MovieListAdapter.itemClick?.invoke(movieTitle)
                }

Now your final code will look like this. You can check How I have handled ItemClick and Item Long Click in the below code.

MovieListViewHolder.kt

class MovieListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    var itemClick: ((String) -> Unit)? = null
    var onItemLongPress: ((MovieModel) -> Unit)? = null

    fun bindView(movieModel: MovieModel) {
        itemView.textMovieTitle.text = movieModel.movieTitle
        itemView.textMovieViews.text = "Views: " + movieModel.movieViews
        itemView.textReleaseDate.text = "Release Date: " + movieModel.releaseDate

        Glide.with(itemView.context).load(movieModel.moviePicture!!).into(itemView.imageMovie)

//        //For Handling RecyclerView Item Click
        itemView?.setOnClickListener {

            //invoke() function will pass the value to receiver function.
            itemClick?.invoke(movieModel.movieTitle)
        }

        //For handling RecyclerView Item Long Click
        itemView?.setOnLongClickListener {
            onItemLongPress?.invoke(movieModel)
            return@setOnLongClickListener true
        }
    }

}

 

MovieListAdapter.kt

class MovieListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private var listOfMovies = mutableListOf<MovieModel>()

    var itemClick: ((String) -> Unit)? = null
    var onItemLongPress: ((MovieModel) -> Unit)? = null
    

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return MovieListViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.list_item_movie, parent, false)).apply {
            itemClick = { movieTitle ->
                this@MovieListAdapter.itemClick?.invoke(movieTitle)
            }

            onItemLongPress = { movieModel ->
                this@MovieListAdapter.onItemLongPress?.invoke(movieModel)
            }
        }
    }

    override fun getItemCount(): Int = listOfMovies.size

    override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {
        val movieViewHolder = viewHolder as MovieListViewHolder
        movieViewHolder.bindView(listOfMovies[position])
    }

}


MainActivity.kt

Just handle events where you declare your adapter.

val movieListAdapter = MovieListAdapter().apply {
                itemClick = { movieTitle ->
                Toast.makeText(this@RecyclerViewLinearLayoutActivity, movieTitle, Toast.LENGTH_SHORT).show()
            }
            onItemLongPress = {movieModel ->
                Toast.makeText(this@RecyclerViewLinearLayoutActivity, movieModel.movieId.toString(), Toast.LENGTH_SHORT).show()
            }
        }

 

How to handle RecyclerView Item Click using Interface?

For this method, you will first need an interface that specifies the listener’s behavior. Create one interface as below.

interface RecyclerViewCallback {
    fun onRecycleViewItemClick(movieModel: MovieModel, position: Int)
    fun onRecycleViewLongPress(movieModel: MovieModel, position: Int)
}

Now make one method to initialize the interface object bypassing the reference of the interface. Something like this

fun setOnCallbackListener(recyclerViewCallback: RecyclerViewCallback) {
        this.recyclerViewCallback = recyclerViewCallback
    }

Let’s check the full code now.

MovieListAdapter.kt

class MovieListAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private var listOfMovies = mutableListOf<MovieModel>()

    var recyclerViewCallback: RecyclerViewCallback? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return MovieListViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.list_item_movie, parent, false)).apply {
            itemView.setOnClickListener {
                this@MovieListAdapter.recyclerViewCallback?.onRecycleViewItemClick(listOfMovies[adapterPosition], adapterPosition)
            }

            itemView.setOnLongClickListener {
                this@MovieListAdapter.recyclerViewCallback?.onRecycleViewLongPress(listOfMovies[adapterPosition], adapterPosition)
                return@setOnLongClickListener true
            }
        }
    }

    override fun getItemCount(): Int = listOfMovies.size

    override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {
        val movieViewHolder = viewHolder as MovieListViewHolder
        movieViewHolder.bindView(listOfMovies[position])
    }

    fun setOnCallbackListener(recyclerViewCallback: RecyclerViewCallback) {
        this.recyclerViewCallback = recyclerViewCallback
    }

}

MovieListViewHolder.kt

class MovieListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    fun bindView(movieModel: MovieModel) {
        itemView.textMovieTitle.text = movieModel.movieTitle
        itemView.textMovieViews.text = "Views: " + movieModel.movieViews
        itemView.textReleaseDate.text = "Release Date: " + movieModel.releaseDate

        Glide.with(itemView.context).load(movieModel.moviePicture!!).into(itemView.imageMovie)
    }

}

MainActivity.kt

In the Activity just create an instance of an adapter and call method to initialize the interface.

val movieListAdapter = MovieListAdapter()
recyclerViewMovies.adapter = movieListAdapter
movieListAdapter.setOnCallbackListener(this)

Conclusion

You can use any of the mentioned methods to handle the RecyclerView Item Click. Personally I recommend using Higher-level function till you don’t need additional data from ViewHolder. If you want additional information like Position, View and Model class as well then I prefer to create Interface.

Source Code

Github link to check How to handle recycler view item click demo.

Related posts

Leave a Reply

Required fields are marked *