在Android Kotlin中,将onclick事件传递给viewholder的正确方法是啥?

Posted

技术标签:

【中文标题】在Android Kotlin中,将onclick事件传递给viewholder的正确方法是啥?【英文标题】:In Android Kotlin, what's the right way to pass a onclick event into a viewholder?在Android Kotlin中,将onclick事件传递给viewholder的正确方法是什么? 【发布时间】:2021-04-15 13:33:06 【问题描述】:

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

第一个:

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

感谢您花时间和精力告诉我这些差异。

【问题讨论】:

【参考方案1】:

从关注点分离的角度来看,所有clickListeners 都应该在ActivityFragmentAdapters 中处理,在您的情况下Flower 和以RecyclerView 可以使用的方式将它们显示在屏幕上。

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

【讨论】:

感谢您的回答!知道它是为了关注点分离会有所帮助。【参考方案2】:

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

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

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

TLDR;

因此,根据您为我们提供的信息,我将使用这两种方法的优点。将回调绑定到bind钩子中,并通过ViewHolder的构造函数传递回调

【讨论】:

哇,这是个好主意,我还没有考虑过将两者结合起来,而且通用适配器听起来不像样板代码

以上是关于在Android Kotlin中,将onclick事件传递给viewholder的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何将参数从 Flutter 传递给 Kotlin?

通过适配器在片段之间传递数据(Kotlin Android)

如何在 Kotlin 中为 Android 的 RecyclerView 适配器初始化 viewHolder

在 xml 定义的活动中找不到 onClick 方法

如何使用 Kotlin 在 RecyclerView Adapter 中实现 onClick 并进行数据绑定

如何在 Android 的 Kotlin 中使用 GSON 将 JSON 对象转换为 JSON 数组