1

Is there any advantage when using RecyclerView.OnItemClickListener over Implementing onClickListener in the viewholder of a recyclerView?

The way i handle click's in a Recycler view is by implementing onClickListener on the ViewHolder as shown below

class MyViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView), View.OnClickListener{
    val my_view : View
    init {
        my_view = itemView.findViewById(R.id.my_view_id)
        my_view.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when (v?.id){
            R.id.my_view_id -> doSomething()
        }
    }
}

Instead of using RecyclerView.OnItemClickListener() as demonstrated at https://stackoverflow.com/a/26196831

Taslim Oseni
  • 4,610
  • 10
  • 34
  • 50
LekeOpe
  • 2,095
  • 1
  • 15
  • 29
  • 1
    the advantage is that you can handle the click in the activity or fragment and do some stuff much easier when you do it inside the adapter. – humazed Feb 24 '18 at 10:01
  • 1
    the way you use it inside your `ViewHolder`: `setOnClickListener(this)` is the way you should follow – pskink Feb 24 '18 at 10:10
  • @pskink thanks but have you tried the Recycler.OnItemClickListener() method, is there any performance gain? – LekeOpe Feb 24 '18 at 10:19
  • @humazed thanks for your input but i don't quite understand what you wrote. Do you mean the Recycler.OnItemClickListener() option is better because i'll be able to handle clicks in an Activity or Fragment? – LekeOpe Feb 24 '18 at 10:22
  • On click listener will be attached for each view holder bind so can be bad for performance if you assign a new click listener every time. The item click listener is attached to the recycler view and can be handled in the fragment. – Kushan Feb 24 '18 at 10:29
  • @Kushan Thanks, are you suggesting RecyclerView.OnItemClickListener() to be ideal? – LekeOpe Feb 24 '18 at 10:37
  • There's no ideal here, either approach is good... What you're currently doing is also good since you aren't attaching a new click listener. It's more about convenience tbh. – Kushan Feb 24 '18 at 10:38
  • @Kushan "you aren't attaching a new click listener." could you please expatiate? – LekeOpe Feb 24 '18 at 10:59
  • @Micklo_Nerd the way you are doing now is perfectly ok - do not try to play with that `GestureDetector` - its really pointless – pskink Feb 24 '18 at 11:02
  • I mean to say that you are not creating an anonymous class listener using the new keyword every single time – Kushan Feb 24 '18 at 11:16
  • @pskink Thanks for pointing that out, i also feel the GestureDetector solution is clunky, pointless and unnecessary, but i had to confirm by adding this question. – LekeOpe Feb 24 '18 at 11:36
  • @Kushan please, indulge me to put it the way i understand you. you mean extending OnClickListener on the ViewHolder is better than attaching annonymous onClickListeners to views? – LekeOpe Feb 24 '18 at 11:38
  • Yes it is.... A new anonymous Will end up creating more stuff for the gc to collect... Android is good and all and it'll mostly clean up good but why make it is the point :) – Kushan Feb 24 '18 at 11:41
  • In short summary, what you're doing is good... Unless you don't want any view which was clicked or all in which case you should use an item click listener... Use your approach. Make a class which extends the click listener, implement the methods in it and apply it in the bind view holder like you have. – Kushan Feb 24 '18 at 11:43
  • Thank you very much @Kushan – LekeOpe Feb 24 '18 at 11:46
  • You're on the right track! This is by far the simplest way I know. – Taslim Oseni Feb 24 '18 at 22:22

1 Answers1

2

The way you are doing is right. A ViewHolder is a required part of the pattern for RecyclerViews. It's also a convenient place to set an OnClickListener, since it has access to the adapter and the views. Take a look on this example provided by Google.

Moreover, using RecyclerView.OnItemClickListener, as @Niranjan mentioned in the comments, will not provide any clue about which button or view (within the item) was clicked.

gts13
  • 860
  • 1
  • 13
  • 25