RecyclerView and CardView Click listener implementation

25,216

Solution 1

If you want to implement onClick for each cardview, you can do like this: in your XML:

<android.support.v7.widget.CardView
    android:id="@+id/card_view">

    ...

</android.support.v7.widget.CardView>

Then, in your adapter code:

public static class ViewHolder extends RecyclerView.ViewHolder {
        private CardView cardView;

        public ViewHolder(View itemView) {
            super(itemView);
            cardView = (CardView) itemView.findViewById(R.id.card_view);
        }
}

...

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //implement onClick
                System.out.println("Clicked");
            }
        });
    }
}

Solution 2

You can pass listener from Adapter to ViewHolder, and listen events there, and you also can pass event from Adapter to your Activity or where you create this Adapter

public class AlbumAdapter extends RecyclerView.Adapter<AlbumAdapter.ViewHolder> {

private List<Album> albums;
private Context context;
public AlbumAdapterClickListener recListener;

public AlbumAdapter(List<Album> albums, Context context, AlbumAdapterClickListener recListener) {
    this.albums = albums;
    this.context = context;
    this.recListener = recListener;
}

public interface AlbumAdapterClickListener {
    void recyclerViewClick(String albumID);
}


public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView title;
    public TextView count;
    public ImageView picture;
    public String albumID;
    public AlbumClickListener listener;

    //listener passed to viewHolder
    public interface AlbumClickListener {
        void albumOnClick(String albumID);
    }

    public ViewHolder(View v, AlbumClickListener listener) {
        super(v);
        title = (TextView) v.findViewById(R.id.album_list_title);
        count = (TextView) v.findViewById(R.id.album_list_count);
        picture = (ImageView) v.findViewById(R.id.album_list_picture);

        this.listener = listener;
        v.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        listener.albumOnClick(this.albumID);
    }
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.album_list_item, viewGroup, false),
            new ViewHolder.AlbumClickListener() {
                @Override
                public void albumOnClick(String albumID) {
                    //TODO show gridView with current albumID
                    Log.e("fdf", albumID);
                    // albumID going to Fragment
                    recListener.recyclerViewClick(albumID);
                }

            });
}


@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    Album album = albums.get(i);
    viewHolder.albumID = album.getId();
    viewHolder.count.setText(album.getPhotoCount());
    viewHolder.title.setText(album.getName());
    Picasso.with(context).load(albums.get(i).getCoverURL()).placeholder(R.mipmap.fb_place_holder).resize(140, 140)
            .centerCrop().into(viewHolder.picture);
}

@Override
public int getItemCount() {
    return albums.size();
}

}

Solution 3

The answer from VLeong works great for me! But a little clarification. This : holder.cardView.setOnClickListener(new View.OnClickListener() { need to be changed to :

holder.itemView.setOnClickListener(new View.OnClickListener(){
Share:
25,216
123
Author by

123

Updated on January 17, 2020

Comments

  • 123
    123 over 4 years

    I just moved into the android RecyclerView and CardViewand ... and realized recyclerview don't have an option for Onclick listner, but after implement this feature, i just don't see any result.

    hear is my code and layouts:

    MainActivity:

    public class MainActivity extends AppCompatActivity {
    
        //private usefulSites_RecyclerView_Adapter mAdapter;
        final Context context = this;
        private RecyclerView mRecyclerView;
        private StaggeredGridLayoutManager mGridLayoutManager;
        private RecyclerViewAdapter mAdapter;
        private String[] mList;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(mToolbar);
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onBackPressed();
                }
            });
            //使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上则不会显示
            CollapsingToolbarLayout mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
            mCollapsingToolbarLayout.setTitle("test");
            //通过CollapsingToolbarLayout修改字体颜色
            mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色
            mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.GREEN);
    
    
            //mList = getResources().getStringArray(R.array.numbers);
    
            mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
            mGridLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
            mRecyclerView.setItemAnimator(new DefaultItemAnimator());
            mRecyclerView.setLayoutManager(mGridLayoutManager);
            mAdapter = new RecyclerViewAdapter(getApplicationContext());
            mRecyclerView.setAdapter(mAdapter);
    
    
        }
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.menu_main, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
    
            //noinspection SimplifiableIfStatement
            if (id == R.id.action_settings) {
                return true;
            }
    
            return super.onOptionsItemSelected(item);
        }
    }
    

    RecyclerViewAdapter

    public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
    
        private Context mContext;
        private String [] mSiteTitle,mSiteLink;
        private int [] mThumbnail;
    
        public RecyclerViewAdapter(Context contexts, String[] list) {
            this.mContext = contexts;
            this.mSiteTitle = list;
        }
        public RecyclerViewAdapter(Context contexts) {
            this.mContext = contexts;
            initList();
        }
        private void initList(){
    
            UsfulSite_init mInit=new UsfulSite_init();
            mSiteTitle= mInit.initSiteTitle();
            mSiteLink=mInit.initSiteLink();
            mThumbnail=mInit.initThumbnail();
    
    
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            View itemView = inflater.inflate(R.layout.usful_sites_card_view, parent, false);
            return new ViewHolder(itemView);
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            holder.sTitle.setText(mSiteTitle[position]);
            holder.sLink.setText(mSiteTitle[position]);
            holder.sImage.setImageResource(mThumbnail[position]);
    
    
            holder.setClickListener(new ItemClickListener() {
                @Override
                public void onClick(View view, int position, boolean isLongClick) {
                    if (isLongClick) {
                        Toast.makeText(mContext, "#" + position + " - " + mSiteTitle[position] + " (Long click)", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(mContext, "#" + position + " - " + mSiteTitle[position], Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    
        @Override
        public int getItemCount() {
            return mSiteTitle.length;
        }
    
        public static class ViewHolder extends RecyclerView.ViewHolder
                implements View.OnClickListener, View.OnLongClickListener{
            private TextView sTitle,sLink;
            private ImageView sImage;
            private ItemClickListener clickListener;
    
            public ViewHolder(View itemView) {
                super(itemView);
                sTitle = (TextView)itemView.findViewById(R.id.useful_sites_Title);
                sLink=(TextView)itemView.findViewById(R.id.useful_sites_Link);
                sImage=(ImageView)itemView.findViewById(R.id.useful_sites_thumbnail);
                itemView.setTag(itemView);
                itemView.setOnClickListener(this);
                itemView.setOnLongClickListener(this);
    
    
            }
    
            public void setClickListener(ItemClickListener itemClickListener) {
                this.clickListener = itemClickListener;
            }
    
            @Override
            public void onClick(View view) {
                clickListener.onClick(view, getPosition(), false);
            }
    
            @Override
            public boolean onLongClick(View view) {
                clickListener.onClick(view, getPosition(), true);
                return true;
            }
        }
    }
    

    Activity_main.xml:

    <android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinatorLayout"
    
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <android.support.design.widget.AppBarLayout
    
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:fitsSystemWindows="true">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
    
            app:contentScrim="#30469b"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
    
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:src="@drawable/a"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7"  />
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none" />
    </LinearLayout>
    

    CardView Layout.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_margin="5dp"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="4dp"
    android:layout_height="match_parent">
    
    <RelativeLayout
    
        android:id="@+id/mainHolder"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/useful_sites_thumbnail"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:scaleType="centerCrop"
            android:tint="@color/photo_tint"
            android:layout_centerInParent="true"
            />
    
        <TextView
            android:id="@+id/useful_sites_Title"
            android:gravity="center"
            android:background="?android:selectableItemBackground"
            android:focusable="true"
            android:clickable="true"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:textSize="24sp"
            android:layout_centerInParent="true"
            android:textColor="@android:color/white"
            />
        <TextView
            android:id="@+id/useful_sites_Link"
            android:gravity="center"
            android:background="?android:selectableItemBackground"
            android:focusable="true"
            android:clickable="true"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:textSize="24sp"
            android:layout_centerInParent="true"
            android:textColor="@android:color/white"
            android:visibility="gone"
            />
    </RelativeLayout>
    

    I tested another ways for clickListner in RV butT, i just stuck in this. can some one look at my code and guide me, Little about this.