1

I am currently trying to set an onClickListner to each item of the list in my RecyclerView. I was wondering which method is the best to this and the pros and cons of each.

I found two ways. This one seems more simpler:

RecyclerView onClick

They just add it to each item in the onCreateViewHolder() method

private final OnClickListener mOnClickListener = new MyOnClickListener();

@Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
    View view = LayoutInflater.from(mContext).inflate(R.layout.myview, parent, false);
    view.setOnClickListener(mOnClickListener);
    return new MyViewHolder(view);
}

The method in this article seems more confusing to me which is creating an interface in the adapter class and implementing it in the Activity file:

https://medium.com/androiddevelopers/android-data-binding-recyclerview-db7c40d9f0e4

What would be the benefit of doing it this way?

efoc
  • 415
  • 1
  • 5
  • 19

3 Answers3

2

I am answering based on what I understood.

There are two places you can attach the listener.

OnCreateViewHolder

This function is called whenever recyclerview can't reuse any existing views and needs to inflate a new view. Remember recyclerview reuses the views which are out of focus.

onBindViewHolder

This function is called whenever any view is coming on the screen and recyclerview wants you to add the proper content to that view.

So at both these functions, you have access to your view and you can set click listeners, the only difference is that in onCreateViewHolder you don't have access to position of the item (remember it doesn't create view for each position it might reuse out of focus views) and in onBindViewHolder you have access to position of the item.

So basically if you need the position of the item for which the view is clicked then you should set it in onBindViewHolder otherwise you can set it in onCreateViewHolder.

I hope this helps! If not please add a comment.

Raj Suvariya
  • 1,258
  • 1
  • 11
  • 29
1

Set click listener in onCreateViewHolder or onBindViewHolder if you need to consume the click event in Adapter class only e.g., removing an item and notifying the adapter or simply show Toast. Only difference is that you get position inside onBindViewHolder.

Second approach of using interface and implementing it in Activity/Fragment is for cases where you need to receive the click event in these parent classes. You pass the interface instance from Activity/Fragment to adapter class and interface method is invoked on click. For better understanding, you can consider the case where you need to make an API call or invoke a ViewModel/Controller function on click of adapter item.

So, both the cases are valid based on your use case. Hope it helps :)

1

Indeed the best approach would be to attach ClickListner to the onBindViewHolder, as the method called once for each child of the recyclerview . Check out this snippet:

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
    final Contact contact = contactListFiltered.get(position);
    holder.tvContactName.setText(contact.personUri.toString());
    holder.tvContactNo.setText(contact.number);
    holder.civContactPic.setImageBitmap(contact.photo);
    holder.cvContactItem.setOnClickListener(v -> Utils.shortToast("" + contact.id, context));
}

On click, it will show contact-id of each child of recyclerview in a toast. On the other hand, if you add ClickListner to onCreateViewHolder, you cant detect which item get clicked and it acts similar to each child of recyclerview, which I don't think you want. So I suggest you to add your ClickListner to onCreateViewHolder.

gpl
  • 1,116
  • 2
  • 3
  • 19