在 Android Kotlin 中,将 onclick 事件传递到 viewholder 的正确方法是什么? TLDR;

问题描述

这两种方式有什么区别吗? 我一直在使用第二种方式,到目前为止它有效,但我在阅读教程文章时找到了第一种方式。

一个

class FlowersAdapter(private val onClick: (Flower) -> Unit) :
listadapter<Flower,FlowersAdapter.FlowerViewHolder>(FlowerDiffCallback) {

/* ViewHolder for Flower,takes in the inflated view and the onClick behavior. */
class FlowerViewHolder(itemView: View,val onClick: (Flower) -> Unit) :
    RecyclerView.ViewHolder(itemView) {
    private val flowerTextView: TextView = itemView.findViewById(R.id.flower_text)
    private val flowerImageView: ImageView = itemView.findViewById(R.id.flower_image)
    private var currentFlower: Flower? = null

    init {
        itemView.setonClickListener {
            currentFlower?.let {
                onClick(it)
            }
        }
    }

    /* Bind flower name and image. */
    fun bind(flower: Flower) {
        currentFlower = flower

        flowerTextView.text = flower.name
        if (flower.image != null) {
            flowerImageView.setimageResource(flower.image)
        } else {
            flowerImageView.setimageResource(R.drawable.rose)
        }
    }
}

}

First way of writing

第二:

class FlowerViewHolder(itemView: View) :
    RecyclerView.ViewHolder(itemView) {
    private val flowerTextView: TextView = itemView.findViewById(R.id.flower_text)
    private val flowerImageView: ImageView = itemView.findViewById(R.id.flower_image)
    private var currentFlower: Flower? = null

    /* Bind flower name and image. */
    fun bind(flower: Flower) {
        currentFlower = flower

        flowerTextView.text = flower.name
        if (flower.image != null) {
            flowerImageView.setimageResource(flower.image)
        } else {
            flowerImageView.setimageResource(R.drawable.rose)
        }

        itemView.setonClickListener {
                onClick(flower)
        }
    }
}

Second way of writing

感谢您告诉我差异的时间和精力。

解决方法

从关注点分离的角度来看,所有的 clickListeners 都应该在 ActivityFragment 中处理,而 Adapters 只是为了包裹项目,在您的情况下 Flower 并以 RecyclerView 可以使用的方式在屏幕上显示它们。

话虽如此,clickListeners 的核心逻辑是从 bind 方法移到活动/片段中,而这正是 firstMethod 的全部意义所在。事实上,我没有注意到使用 FirstMethod 比使用第二个有任何性能改进,但我坚持使用 FirstOne,因为它更多的是代码组织。

,

恕我直言,我觉得适配器应该对点击侦听器或有关 ViewHolder 的任何详细信息一无所知;所以我不会通过适配器传递回调。

我喜欢将回调传递给我的 ViewHolder,但我没有映射到 init 块,而是在来自适配器的 onBind 钩子上执行它,在那里我将视图作为参数接收。此外,我将 ViewHolder 直接传递或更新到我的 Adapter 中。然后有一些通用函数来计算数据集是否发生了变化。

如果你这样做,你的好处是你可以构建 1 个通用适配器并在其他地方使用它,而不必真正关心稍后可能需要实现多少不同类型的 ViewHolder,因为它是完全不可知的.

TLDR;

因此,根据您提供给我们的信息,我会利用这两种方法的优点。将回调绑定到 bind 钩子并通过 ViewHolder

的构造函数传递回调