28

How do I attach an OnClickListener to a CardView? I want every single card to have a different action when clicked.

I have a RecyclerView that has a custom adapter for displaying the cards. This is how it's implemented.

SpaceCore186
  • 586
  • 1
  • 8
  • 22
MikkoP
  • 4,864
  • 16
  • 58
  • 106

4 Answers4

41

You should implement the OnItemClickListener in your ViewHolder class, and pass the current item to the ViewHolder instances on every onBindViewHolder().

From this post:

public static class ViewHolder extends RecyclerView.ViewHolder {
    public View view;
    public Item currentItem;

    public ViewHolder(View v) {
        super(v);
        view = v;
        view.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                // item clicked
            }
        });
    }
}

@Override public void onBindViewHolder(ViewHolder viewHolder, int i) {
    viewHolder.currentItem = items.get(i);
}
SpaceCore186
  • 586
  • 1
  • 8
  • 22
Andras K
  • 932
  • 9
  • 15
  • Thanks for the link. I defined the listener there. – MikkoP Nov 23 '14 at 11:55
  • Can you elaborate your answer bit more....how I can know which cardView row is clicked.....If I use view,getId() it returns same id. – Crawler Jul 22 '15 at 16:03
  • 2
    @Crawler you call `getAdapterPosition()` to get it's index in the list. – J.G.Sebring Aug 06 '15 at 12:36
  • 1
    Are there any differences than doing it [this way](http://www.vogella.com/tutorials/AndroidRecyclerView/article.html#recycleview_layouts)? – Derek 朕會功夫 Jan 12 '16 at 05:19
  • 3
    This didn't work for me. When I clicked the cards, nothing happened. But when I clicked just OUTSIDE the cards, the onClick event triggered. I'm assuming the CardView was absorbing the click event, preventing the above OnClick event from firing. EDIT: Ok, I got it to work. The problem was my CardView had it's 'clickable' property set to true. Once I removed that, the above code started handling OnClick events properly. Thanks! – SuperStubbs Apr 13 '16 at 03:26
5

This is my solution for this problem:

  1. First add reference to View view object in ViewHolder class

    public static class TouristViewHolder extends RecyclerView.ViewHolder{
        public ImageView img;
        public TextView name;
        public TextView description;
        public RatingBar rating;
        public View view;               // <----- here
    
        public TouristViewHolder(final View view) {
            super(view);
            this.view = view;            // <----- here
            // ... rest of code
       }
    }
    
  2. Next, in method onBindViewHolder(final MyViewHolder holder, final int position), I add a listener and set new Intent.

    @Override
    public void onBindViewHolder(TouristViewHolder touristViewHolder, final int position) {
    
    touristViewHolder.view.setOnClickListener(new View.OnClickListener() {  // <--- here
        @Override
        public void onClick(View v) {
            Log.i("W4K","Click-"+position);
            context.startActivity(new Intent(context,MainActivity.class));  // <--- here
        }
    });
    

It works for me fine, hope it will help someone else.

Satan Pandeya
  • 3,747
  • 4
  • 27
  • 53
Marek Bodziony
  • 341
  • 3
  • 7
  • Thisi is working perfectly but I think accepted answer is great because you are accessing instance method of `TouristViewHolder ` in overrides. Adding it when initialized in constructor is great **I think**. – Blasanka Jan 04 '20 at 16:10
  • In my case, I had to replace context with ````v.getContext()```` – Shardul Birje Oct 17 '21 at 07:38
3
  1. you just add onClick Listener, which Item you want in onBindViewHolder. where easily accessing the value of that position. please check the below code.

     @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
    
        holder.title.setText(Html.fromHtml(html2text(results.get(position).getTitle().toString())));
        holder.description.setText(Html.fromHtml(html2text(results.get(position).getSummary().toString())));
        holder.url.setText(Html.fromHtml(html2text(results.get(position).getUrl().toString())));
        holder.url.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent=new Intent(mContext, DetailsActivity.class);
                intent.putExtra("url",results.get(position).getUrl().toString());
               mContext. startActivity(intent);
    
            }
        });
    
Kona Suresh
  • 1,836
  • 1
  • 15
  • 25
3

Hello everybody this worked :

   cardView=findViewById(R.id.cardView);
    cardView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(getApplicationContext(),"clicked",Toast.LENGTH_SHORT).show();
        }
    });