Open In App

Kotlin Lambda Functions For RecyclerView Adapter Callbacks in Android

Improve
Improve
Like Article
Like
Save
Share
Report

Are you using old lengthy java fashioned way of creating & handling callbacks in Android with Interfaces? If yes then it’s a very good time to switch on Kotlin Lambda Functions or Higher Order Functions to create & handle callbacks. It’s a much short, simpler & easy way.

Let’s first quickly have a look at older java style way

Remember when you need to implement click functionality on your RecyclerView items, you create an interface that has all the methods to handle your RecyclerView items different clicks and you implement all those functions of interface inside your activity/fragment to perform some actions (for ex: to navigate from current screen to another or something else). And then you pass the reference of that interface into your adapter via the constructor. Then we use that interface in the Adapter to invoke/call its functions to generate callbacks inside activity/fragment. Now look how long the process is and here comes the power of Kotlin in play… Let’s see

Kotlin Lambda Functions for adapter callbacks

First, say bye to the lengthy interface way…. we will now add the lambda function as an argument in our adapter’s constructor. We are taking MoviesAdapter as an example that takes moviesList & lambda function named ‘onItemClicked’ as an argument & in our lambda function ‘onItemClicked’ we have added movie object as an argument so that we can receive this movie object in this lambda function’s callback in our fragment/activity.

Kotlin




class MoviesAdapter(
    private var moviesList: List<Movie>,
    // Here we have added lambda function
    // named 'onItemClicked' as an argument
    // that will itself take movie object as an
    // argument & will return unit means nothing
    private var onItemClicked: ((movie: Movie) -> Unit)
) : RecyclerView.Adapter<MoviesAdapter.ViewHolder>() {
 
 
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        // Just to show as an example we took layout
        // 'MovieItem' as recyclerview items/views.
        val binding = MovieItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return ViewHolder(binding)
    }
 
 
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        // getting a movie from movieList &
        // passing in viewholder's bind function
        holder.bind(moviesList[position])
    }
     
    inner class ViewHolder(val binding: MovieItemBinding) : RecyclerView.ViewHolder(binding.root) {
     
        fun bind(movie: Movie) = binding.apply {
            // Just setting movie details to
            // movieName & movieDescription textviews
            tvMovieName.text = movie.name
            tvMovieDescription.text = movie.description
           
            // Adding clickListener to
            // root layout of this item
            root.setOnClickListener {
                // Invoking this lambda function so that
                // it can give callback in our activity/fragment
                // We are also passing movie object
                // in it while invoking/calling it
                 onItemClicked(movie)
            }
        }
    }
 
    override fun getItemCount(): Int {
        return languageList.size
    }
}


In this example, we are using Viewbinding in RecyclerView Adapter. Now let’s move inside Viewholder’s bind function, inside it, we are simply setting movie details like movie name, description to RecyclerView items and we have to add click functionality to every RecyclerView item so that we can perform some action on click. So, in clickListener of our item’s root, we are actually invoking our lambda function onItemClicked & passing movie in it. So this way we’ll receive a callback in our fragment/activity as it’ll get invoked here on item click. Now let’s see how…

Let’s create the adapter’s object & pass Lambda Function in it

We are taking MovieListFragment as an example here:

Kotlin




class MovieListFragment : Fragment() {
 
    // Declaring moviesAdapter with lateinit
    private lateinit var moviesAdapter: MoviesAdapter
   
    // using viewbinding
    private var _binding: FragmentMovieListBinding? = null
    private val binding get() = _binding!!
 
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentMovieListBinding.inflate(inflater, container, false)
        return binding.root
    }
 
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
 
        // Assume that getMoviesList() is returning
        // list of movies let's say from api call
        val moviesList : List<Movie> = getMoviesList()
         
        // Setting up movies recyclerview
        binding.moviesRecyclerView.layoutManager = LinearLayoutManager(requireContext())
        binding.moviesRecyclerView.setHasFixedSize(true)
      
        // Instantiating moviesAdapter & passing
        // lambda function in it's constructor
        moviesAdapter = MoviesAdapter(moviesList) { it: Movie ->
            // Here we'll receive callback of
            // every recyclerview item click
            // Now, perform any action here.
            // for ex: navigate to different screen
        }
         
        // Setting adapter to moviesRecyclerView
        binding.moviesRecyclerView.adapter = moviesAdapter
    }
}


Here, we are simply instantiating moviesAdapter so it’ll require us to pass the list of movies & lambda functions in its constructor. So now, here in the lambda function block, we are getting a movie object, which means whenever this lambda function will be invoked from the adapter, we’ll receive a callback here with the movie object and now we can perform any action that we want under this lambda function block. That’s it, that’s how we use Kotlin Lambda Functions for RecyclerView adapter callbacks instead of interfaces.

Note: We can use these lambda functions for creating/handling callbacks not only in recyclerview’s adapter but wherever we want this type of functionality in our project.



Last Updated : 29 Mar, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads