如何处理 RecyclerView 列表项内视图的点击。使用数据绑定和科特林

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

我找到的所有资源要么在 Java 中,要么只包含单击列表项本身而不是列表项内部的视图。我相信我应该在 ViewHolder class 中设置它,但我不确定如何设置。这是我的 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()
    }
}

还有我的听众

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

fun onClick(item : Item){

    clickListener(item)


}

}

其他相关的方法调用

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)))
}

如果点击了您可以在 onBindViewHolder

上设置的项目
holder.itemView.setOnClickListener {
        clickListener.onClick(getItem(position)
}

如果您需要项目内部的特定视图,您可以在 bind 函数上设置

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

首先,Listener应该是一个接口。

interface ItemListListener {
    fun onClick(item: Item,actionType:String) 
}

然后在Activity/Fragmentclass中实现这个接口。 初始化适配器。

recyclerView.adapter  = ItemListAdapter(this)

您可以使用以下代码更新您的 ItemViewHolder class。使它成为inner class,那么你就不需要传递clickListener实例了。点击监听器应该在 View Holder class.

init 方法中注册
 inner class ItemViewHolder(private val binding : ItemListItemBinding) :
            RecyclerView.ViewHolder(binding.root) {

              init {
                    binding.addOneButton.setOnClickListener {
                      clickListener.onClick(getItem(adapterPosition),"button")
                 }
                  binding.root.setOnClickListener {
                      clickListener.onClick(getItem(adapterPosition),"root")
                 }
             }
            fun bind(item : Item) {
                binding.item = item
                binding.executePendingBindings()
            }
        }

** 更新 **

经过一番研究,我得到了您问题的答案。 这是解决方案。 您可以将高阶函数传递给适配器 class.

而不是接口
class ItemListAdapter(val clickListener : (Item,String) -> Unit ):ListAdapter<Item , ItemListAdapter.ItemViewHolder>(DiffCallback)

在视图持有者中class

binding.addOneButton.setOnClickListener {
                      clickListener(getItem(adapterPosition),"button")
                 }
                  binding.root.setOnClickListener {
                      clickListener(getItem(adapterPosition),"root")
                 }

在Activity/Fragment

recyclerview.adapter = ItemListAdapter({item, action->
})

您也可以使用绑定来完成。