Home > Mobile >  How to handle clicks on a view inside of a RecyclerView list item. Using data binding and kotlin
How to handle clicks on a view inside of a RecyclerView list item. Using data binding and kotlin

Time:12-05

All of the resources I've found are either in Java or only cover clicking the list item itself not a view inside of the list item. I believe I am supposed to set this up inside the ViewHolder class but I am not sure how. This is my ViewHolder class.

class ItemListAdapter(val clickListener : ItemListListener) : ListAdapter<Item , ItemListAdapter.ItemViewHolder>(DiffCallback) {

class ItemViewHolder(private var binding : ItemListItemBinding) :
    RecyclerView.ViewHolder(binding.root) {
    fun bind(item : Item, clickListener : ItemListListener) {

        binding.item = item
        binding.clickListener = clickListener
        
        // button that inside listItem that I want to respond to clicks
        // binding.addOneButton ???????
        

        binding.executePendingBindings()
    }
}

And my listener

class ItemListListener(val clickListener : (singleItem : Item) -> Unit) {

fun onClick(item : Item){

    clickListener(item)


}

}

Other method calls in case they are relevant

override fun onBindViewHolder(holder : ItemViewHolder , position : Int) {
    val item = getItem(position)
    holder.bind(item, clickListener)
}

companion object DiffCallback : DiffUtil.ItemCallback<Item>() {
    override fun areItemsTheSame(oldItem : Item , newItem : Item) : Boolean {
        return oldItem == newItem
    }

    override fun areContentsTheSame(oldItem : Item , newItem : Item) : Boolean {
        return oldItem.itemId == newItem.itemId
    }
}

override fun onCreateViewHolder(
    parent : ViewGroup ,
    viewType : Int
) : ItemViewHolder {
    return ItemViewHolder(ItemListItemBinding.inflate(LayoutInflater.from(parent.context)))
}

CodePudding user response:

if its a click on the item you can set on the onBindViewHolder

holder.itemView.setOnClickListener {
        clickListener.onClick(getItem(position)
}

If you need on a specific view inside your item you can set on the bind function

fun bind(item : Item, clickListener : ItemListListener) {
    binding.item = item
    binding.addOneButton.setOnClickListener {
         clickListener.onClick(item)
    }
    
    binding.executePendingBindings()
}

CodePudding user response:

First of All, Listener is supposed to be an Interface.

interface ItemListListener {
    fun onClick(item: Item) 
}

Then in Activity/Fragment class,implement this interface. Initialize adapter.

recyclerView.adapter  = ItemListAdapter(this)

You can update your ItemViewHolder class with following code. Make it inner class, Then you'll not need to pass clickListener instance. And click listener should be registered in init method of View Holder class.

 inner class ItemViewHolder(private val binding : ItemListItemBinding) :
            RecyclerView.ViewHolder(binding.root) {

              init {
                    binding.addOneButton.setOnClickListener {
                      clickListener.onClick(getItem(adapterPosition))
                 }
             }
            fun bind(item : Item) {
                binding.item = item
                binding.executePendingBindings()
            }
        }
  • Related