Android |在 ViewHolder onClick 上更新 RecyclerView Adapter

Android | Update RecyclerView Adapter on ViewHolder onClick

我希望我的 'heart' 图标在我的 ViewHolder 项目被点击时发生变化。 幸运的是,它做到了这一点。但是,出现了一个问题,因为多个项目似乎复制了按钮点击。

我的意思是: 如果我在项目编号 1 上点击心脏。列表中的其他项目复制也会改变心脏。 为什么会发生这种情况,潜在的解决方法是什么?当我引用 ViewHolder 项目时,我很困惑为什么会出现此问题。因此,它不应该只影响我点击的项目吗?

视图持有人

        fun bind(item: Location) {
            heart.setOnClickListener {
                item.fav = item.fav != true
                heart.setImageDrawable(
                when (item.fav) {
                    false -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_border_heart))
                    else -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_whole_heart))
                })

            }
        }

However, an issue arises as multiple items seems to replicate the button click.

是因为细胞回收机制

heart.setImageDrawable(
   when (item.fav) {
       false -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_border_heart))
       else -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_whole_heart))
})

应该是 viewholder 中绑定函数的一部分,而不是 onClick 函数的一部分。我期望的是

  • 点击通知视图模型
  • Viewmodel 更新数据集
  • Viewmodel 通知 recyclerview

您没有在 onClick 方法中检查视图 ID。您可以直接在视图上设置onClick,如下所示。

    class LocationViewHolder(v: View): RecyclerView.ViewHolder(v), View.OnClickListener {

private val actLoc: TextView = v.findViewById(R.id.location_main)
private val genLoc: TextView = v.findViewById(R.id.location_subtitle)
private val heart: ImageView = v.findViewById(R.id.heart)
private lateinit var item: Location

fun bind(item: Location) {
    this.item = item
    actLoc.setText(item.actualLocation)
    actLoc.setOnClickListener {
        Toast.makeText(itemView.context, "${item.cords}", Toast.LENGTH_SHORT).show()
    }
    genLoc.setText(item.genLocation)
    genLoc.setOnClickListener {
        Toast.makeText(itemView.context, "${item.cords}", Toast.LENGTH_SHORT).show()
    }
    heart.setOnClickListener {
        item.fav = item.fav != true
        heart.setImageDrawable(
            when (item.fav) {
                false -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_border_heart))
                else -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_whole_heart))
            })

    }
}

onBindViewHolder 您需要根据该列表在更改项目图像中保存最喜欢的列表,否则它会随着视图重新创建而随机更改

     fun bind(item: Location) {

 heart.setImageDrawable(
                when (item.fav) {
                    false -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_border_heart))
                    else -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_whole_heart))
                })
            heart.setOnClickListener {
                item.fav = item.fav != true
                heart.setImageDrawable(
                when (item.fav) {
                    false -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_border_heart))
                    else -> (ContextCompat.getDrawable(itemView.context, R.drawable.ic_whole_heart))
                })

            }
        }