【问题标题】:How to handle clicks on a view inside of a RecyclerView list item. Using data binding and kotlin如何处理对 RecyclerView 列表项内部视图的点击。使用数据绑定和 kotlin
【发布时间】:2022-01-10 19:38:33
【问题描述】:

我找到的所有资源都使用 Java 或仅涵盖单击列表项本身而不是列表项内部的视图。我相信我应该在 ViewHolder 类中设置它,但我不确定如何设置。这是我的 ViewHolder 类。

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

【问题讨论】:

  • 什么是binding.clickListener?你的 XML 中有这个名字的东西吗?
  • 这是我上面第二个代码组中的 ItemListListener。
  • 我的意思是你是如何在你的 XML 中使用它的?有没有设置成xml按钮的onClick属性?
  • 设置为onClick,用于列表项的根视图,一个ConstraintLayout。
  • 你想要两个点击监听器吗?一个用于根视图,一个用于addOneButton?

标签: android kotlin android-recyclerview android-databinding


【解决方案1】:

如果它点击你可以在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()
}

【讨论】:

  • 我实际上已经尝试过了,但奇怪的是,点击最终只在回收站视图的第一个列表项上注册。
【解决方案2】:

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

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

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

recyclerView.adapter  = ItemListAdapter(this)

您可以使用以下代码更新您的 ItemViewHolder 类。将其设为 inner 类,则无需传递 clickListener 实例。并且点击监听器应该注册在 View Holder 类的 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 ItemListAdapter(val clickListener : (Item,String) -> Unit ):ListAdapter<Item , ItemListAdapter.ItemViewHolder>(DiffCallback)

在 View Holder 类中

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

在活动/片段中

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

您也可以使用 Binding 来做到这一点。

【讨论】:

  • 我试图避免做一个界面。我听说在 Kotlin 中有一种不同的实现方式。
  • @brandNoob 接口或 XML 中的绑定侦听器是两种方法。我不知道你说的另一种方式。此外,如果您想分别处理根视图单击和 addOneButton 单击。然后可以在接口类的 onClick 方法中再添加一个参数。我已经更新了你可以查看的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 1970-01-01
  • 2021-09-14
  • 1970-01-01
  • 2017-09-19
  • 2023-03-22
相关资源
最近更新 更多