In Android Kotlin, what's the right way to pass a onclick event into a viewholder?

感情迁移 提交于 2021-01-29 06:00:41

问题


Is there any difference in these two ways? I've been using the seond way and it works so far, yet I found the first way upon reading tutorial articles.

1st:

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

2nd:

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

Appreicate your time and effort in telling me the differences.


回答1:


From the perceptive of separation of concern, all the clickListeners are supposed to be handled in the Activity or Fragment and Adapters are meant just to wrap around the items, in your case Flower and present them in a way which can be used by the RecyclerView to display on the screen.

With that being said, the core logic of clickListeners is to be moved out of the bind method into the activity/fragment and that's precisely whats the firstMethod is all about. Matter of fact, I haven't noticed any performance improvement by employing the FirstMethod over the second one yet I insist on using FirstOne because its more of code organizing.




回答2:


IMHO I feel like the adapter should know nothing about click listeners or any details about the ViewHolder; so I wouldn't pass the callback through the adapter.

I like passing the callback to my ViewHolder but instead of mapping into the init block I do it on the onBind hook from the adapter where I receive the view as a parameter. Also, I pass or update the ViewHolders directly into my Adapters. And then have some generic functions to compute whether the data-set has changed or not.

If you do it like this, you have the benefit that you may build 1 generic adapter and use it elsewhere without really minding how many different types of ViewHolder you may have to implement later on as it is completely agnostic.

TLDR;

So based on what you've provided us I would use the good things of both approaches. Binding the callback into the bind hook and passing the callback through the constructor of the ViewHolder



来源:https://stackoverflow.com/questions/65652780/in-android-kotlin-whats-the-right-way-to-pass-a-onclick-event-into-a-viewholde

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!