CardView is another major element introduced in Material Design. Using CardView you can represent the information in a card manner with a drop shadow (elevation) and corner radius which looks consistent across the platform. CardView extends the FrameLayout and it is supported way back to Android 2.x.
You can achieve good looking UI when CardView is combined with RecyclerView. In this article we are going to learn how to integrate CardView with RecyclerView by creating a beautiful music app that displays music albums with a cover image and title.
How to Add CardView?
To use the CardView in your app, add the CardView dependency in build.gradle and Sync the project.
dependencies { // CardView compile 'com.android.support:cardview-v7:23.3.+' }
Add the <android.support.v7.widget.CardView> widget to your layout and place other UI widgets like TextViews, ImageViews inside it. You can notice that the below CardView widget contains a single TextView.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:card_view="http://schemas.android.com/apk/res-auto"> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_gravity="center" android:layout_width="250dp" android:layout_height="250dp" card_view:cardCornerRadius="4dp"> <TextView android:text="Hello Card" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v7.widget.CardView> </LinearLayout>
Now let’s see this in action by creating a new project.
1. Creating New Project
1. Create a new project in Android Studio from File ⇒ New Project. When it prompts you to select the default activity, select Empty Activity and proceed.
2. Download this res.zip and add them to your projects res folder. This res folder contains few album covers and icons required for this project.
3. Add the below strings, colors and dimen resources to strings.xml, colors.xml and dimens.xml files.
<resources> <string name="app_name">Card View</string> <string name="action_settings">Settings</string> <string name="action_add_favourite">Add to Favourites</string> <string name="action_play_next">Play Next</string> <string name="backdrop_title">LOVE MUSIC</string> <string name="backdrop_subtitle">This season top 20 albums</string> </resources>
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#F50057</color> <color name="colorPrimaryDark">#F50057</color> <color name="colorAccent">#FF4081</color> <color name="viewBg">#f1f5f8</color> <color name="album_title">#4c4c4c</color> </resources>
<resources> <!-- Default screen margins, per the Android Design guidelines. --> <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> <dimen name="fab_margin">16dp</dimen> <dimen name="item_offset">10dp</dimen> <dimen name="detail_backdrop_height">250dp</dimen> <dimen name="backdrop_title">30dp</dimen> <dimen name="backdrop_subtitle">18dp</dimen> <dimen name="card_margin">5dp</dimen> <dimen name="card_album_radius">0dp</dimen> <dimen name="album_cover_height">160dp</dimen> <dimen name="album_title_padding">10dp</dimen> <dimen name="album_title">15dp</dimen> <dimen name="songs_count_padding_bottom">5dp</dimen> <dimen name="songs_count">12dp</dimen> <dimen name="ic_album_overflow_width">20dp</dimen> <dimen name="ic_album_overflow_height">30dp</dimen> <dimen name="ic_album_overflow_margin_top">10dp</dimen> </resources>
4. Open build.gradle and add CardView, RecyclerView and Glide dependencies. RecyclerView is used to display the albums in grid manner. CardView is used to display single album item. Glide is used to display the album cover images.
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.android.support:design:23.3.0' // RecyclerView compile 'com.android.support:recyclerview-v7:23.3.+' // CardView compile 'com.android.support:cardview-v7:23.3.+' // Glide compile 'com.github.bumptech.glide:glide:3.7.0' }
5. To create instance of a single album, we need a model class denoting the album properties like name, number of songs and cover image. So create a class named Album.java and add the below code.
package info.androidhive.cardview; /** * Created by Lincoln on 18/05/16. */ public class Album { private String name; private int numOfSongs; private int thumbnail; public Album() { } public Album(String name, int numOfSongs, int thumbnail) { this.name = name; this.numOfSongs = numOfSongs; this.thumbnail = thumbnail; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getNumOfSongs() { return numOfSongs; } public void setNumOfSongs(int numOfSongs) { this.numOfSongs = numOfSongs; } public int getThumbnail() { return thumbnail; } public void setThumbnail(int thumbnail) { this.thumbnail = thumbnail; } }
6. We also need an xm layout to display the album card. Create an xml layout named album_card.xml under res ⇒ layout. Here you can notice that I have added <android.support.v7.widget.CardView> and added all the album properties like name, number of songs and cover image inside it. I also added a 3 dot icon which shows a popup menu on tapping it.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.CardView android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:layout_margin="@dimen/card_margin" android:elevation="3dp" card_view:cardCornerRadius="@dimen/card_album_radius"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/thumbnail" android:layout_width="match_parent" android:layout_height="@dimen/album_cover_height" android:background="?attr/selectableItemBackgroundBorderless" android:clickable="true" android:scaleType="fitXY" /> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/thumbnail" android:paddingLeft="@dimen/album_title_padding" android:paddingRight="@dimen/album_title_padding" android:paddingTop="@dimen/album_title_padding" android:textColor="@color/album_title" android:textSize="@dimen/album_title" /> <TextView android:id="@+id/count" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/title" android:paddingBottom="@dimen/songs_count_padding_bottom" android:paddingLeft="@dimen/album_title_padding" android:paddingRight="@dimen/album_title_padding" android:textSize="@dimen/songs_count" /> <ImageView android:id="@+id/overflow" android:layout_width="@dimen/ic_album_overflow_width" android:layout_height="@dimen/ic_album_overflow_height" android:layout_alignParentRight="true" android:layout_below="@id/thumbnail" android:layout_marginTop="@dimen/ic_album_overflow_margin_top" android:scaleType="centerCrop" android:src="@drawable/ic_dots" /> </RelativeLayout> </android.support.v7.widget.CardView> </LinearLayout>
7. Create a menu file named menu_album.xml under res ⇒ menu folder. This menu will be shown as popup menu on tapping on dots icons on each album card item.
<menu 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"> <item android:id="@+id/action_add_favourite" android:orderInCategory="100" android:title="@string/action_add_favourite" /> <item android:id="@+id/action_play_next" android:orderInCategory="101" android:title="@string/action_play_next" /> </menu>
8. To render the RecyclerView, we need an adapter class which inflates the album_card.xml by keeping appropriate information. Create a class named AlbumsAdapter.java and add the below content.
package info.androidhive.cardview; import android.content.Context; import android.support.v7.widget.PopupMenu; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.bumptech.glide.Glide; import java.util.List; /** * Created by Ravi Tamada on 18/05/16. */ public class AlbumsAdapter extends RecyclerView.Adapter<AlbumsAdapter.MyViewHolder> { private Context mContext; private List<Album> albumList; public class MyViewHolder extends RecyclerView.ViewHolder { public TextView title, count; public ImageView thumbnail, overflow; public MyViewHolder(View view) { super(view); title = (TextView) view.findViewById(R.id.title); count = (TextView) view.findViewById(R.id.count); thumbnail = (ImageView) view.findViewById(R.id.thumbnail); overflow = (ImageView) view.findViewById(R.id.overflow); } } public AlbumsAdapter(Context mContext, List<Album> albumList) { this.mContext = mContext; this.albumList = albumList; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.album_card, parent, false); return new MyViewHolder(itemView); } @Override public void onBindViewHolder(final MyViewHolder holder, int position) { Album album = albumList.get(position); holder.title.setText(album.getName()); holder.count.setText(album.getNumOfSongs() + " songs"); // loading album cover using Glide library Glide.with(mContext).load(album.getThumbnail()).into(holder.thumbnail); holder.overflow.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { showPopupMenu(holder.overflow); } }); } /** * Showing popup menu when tapping on 3 dots */ private void showPopupMenu(View view) { // inflate menu PopupMenu popup = new PopupMenu(mContext, view); MenuInflater inflater = popup.getMenuInflater(); inflater.inflate(R.menu.menu_album, popup.getMenu()); popup.setOnMenuItemClickListener(new MyMenuItemClickListener()); popup.show(); } /** * Click listener for popup menu items */ class MyMenuItemClickListener implements PopupMenu.OnMenuItemClickListener { public MyMenuItemClickListener() { } @Override public boolean onMenuItemClick(MenuItem menuItem) { switch (menuItem.getItemId()) { case R.id.action_add_favourite: Toast.makeText(mContext, "Add to favourite", Toast.LENGTH_SHORT).show(); return true; case R.id.action_play_next: Toast.makeText(mContext, "Play next", Toast.LENGTH_SHORT).show(); return true; default: } return false; } } @Override public int getItemCount() { return albumList.size(); } }
9. Open the layout files main activity activity_main.xml and content_main.xml, add AppBarLayout, CollapsingToolbarLayout, Toolbar and RecyclerView.
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/white" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="@dimen/detail_backdrop_height" android:fitsSystemWindows="true" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginEnd="64dp" app:expandedTitleMarginStart="48dp" app:expandedTitleTextAppearance="@android:color/transparent" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/backdrop" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:scaleType="centerCrop" app:layout_collapseMode="parallax" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:id="@+id/love_music" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/backdrop_title" android:textColor="@android:color/white" android:textSize="@dimen/backdrop_title" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/backdrop_subtitle" android:textColor="@android:color/white" android:textSize="@dimen/backdrop_subtitle" /> </LinearLayout> </RelativeLayout> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main" /> </android.support.design.widget.CoordinatorLayout>
content_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" android:background="@color/viewBg" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="info.androidhive.cardview.MainActivity" tools:showIn="@layout/activity_main"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipToPadding="false" android:scrollbars="vertical" /> </RelativeLayout>
10. Finally open MainActivity.java and do the necessary changes.
> initCollapsingToolbar() – Shows or hides the toolbar title when the toolbar is collapsed or expanded.
> prepareAlbums() – Adds sample albums data required for the recycler view.
> GridLayoutManager is used to display the RecyclerView in Grid manner instead of list.
> GridSpacingItemDecoration is used to give equal margins around RecyclerView grid items.
> AlbumsAdapter instance is created and assigned to RecyclerView which renders the CardView albums in grid fashion.
package info.androidhive.cardview; import android.content.res.Resources; import android.graphics.Rect; import android.os.Bundle; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CollapsingToolbarLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.util.TypedValue; import android.view.View; import android.widget.ImageView; import com.bumptech.glide.Glide; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private AlbumsAdapter adapter; private List<Album> albumList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); initCollapsingToolbar(); recyclerView = (RecyclerView) findViewById(R.id.recycler_view); albumList = new ArrayList<>(); adapter = new AlbumsAdapter(this, albumList); RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(this, 2); recyclerView.setLayoutManager(mLayoutManager); recyclerView.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(10), true)); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setAdapter(adapter); prepareAlbums(); try { Glide.with(this).load(R.drawable.cover).into((ImageView) findViewById(R.id.backdrop)); } catch (Exception e) { e.printStackTrace(); } } /** * Initializing collapsing toolbar * Will show and hide the toolbar title on scroll */ private void initCollapsingToolbar() { final CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar); collapsingToolbar.setTitle(" "); AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar); appBarLayout.setExpanded(true); // hiding & showing the title when toolbar expanded & collapsed appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { boolean isShow = false; int scrollRange = -1; @Override public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { if (scrollRange == -1) { scrollRange = appBarLayout.getTotalScrollRange(); } if (scrollRange + verticalOffset == 0) { collapsingToolbar.setTitle(getString(R.string.app_name)); isShow = true; } else if (isShow) { collapsingToolbar.setTitle(" "); isShow = false; } } }); } /** * Adding few albums for testing */ private void prepareAlbums() { int[] covers = new int[]{ R.drawable.album1, R.drawable.album2, R.drawable.album3, R.drawable.album4, R.drawable.album5, R.drawable.album6, R.drawable.album7, R.drawable.album8, R.drawable.album9, R.drawable.album10, R.drawable.album11}; Album a = new Album("True Romance", 13, covers[0]); albumList.add(a); a = new Album("Xscpae", 8, covers[1]); albumList.add(a); a = new Album("Maroon 5", 11, covers[2]); albumList.add(a); a = new Album("Born to Die", 12, covers[3]); albumList.add(a); a = new Album("Honeymoon", 14, covers[4]); albumList.add(a); a = new Album("I Need a Doctor", 1, covers[5]); albumList.add(a); a = new Album("Loud", 11, covers[6]); albumList.add(a); a = new Album("Legend", 14, covers[7]); albumList.add(a); a = new Album("Hello", 11, covers[8]); albumList.add(a); a = new Album("Greatest Hits", 17, covers[9]); albumList.add(a); adapter.notifyDataSetChanged(); } /** * RecyclerView item decoration - give equal margin around grid item */ public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration { private int spanCount; private int spacing; private boolean includeEdge; public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) { this.spanCount = spanCount; this.spacing = spacing; this.includeEdge = includeEdge; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { int position = parent.getChildAdapterPosition(view); // item position int column = position % spanCount; // item column if (includeEdge) { outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing) outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing) if (position < spanCount) { // top edge outRect.top = spacing; } outRect.bottom = spacing; // item bottom } else { outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing) outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing) if (position >= spanCount) { outRect.top = spacing; // item top } } } } /** * Converting dp to pixel */ private int dpToPx(int dp) { Resources r = getResources(); return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics())); } }
If you run the app now, you can see the album CardViews displayed in a grid.
Hi there! I am Founder at androidhive and programming enthusiast. My skills includes Android, iOS, PHP, Ruby on Rails and lot more. If you have any idea that you would want me to develop? Let’s talk: ravi@androidhive.info
how to use recycler view with firebase to show images and text in a 2 column grid..plz help
sir can u tell that when we click on one item and onclick a new detailed activty is open with larger image and full details of card views plz give any perfect tutorial link thanks to androidhive admins
Excelente!
Very much appreciated for your excellent example.
Thank you.
When i import your project i am facing ProcessNotCreated exception any help here.. i am completely new to Android
Thank you for the work you do
Ravi Tamada
Happy to be among you
Happy to be among you
You are welcome 🙂
I am a fan of Indian Kitchen
I send you a proposal a project
please reply me I know you have a lot of work but try to see
thank you
धन्यवाद
Reply me for the project I send
thank you
first of all thank you very much for a simple explanation of cardlayout, but what if I want to know which card/position menu is clicked?
I am a fan of Indian Kitchen
I send you a proposal a project
please reply me I know you have a lot of work but try to see
thank you
धन्यवाद
Bhai good going… Thanks for you usefull tuts ?
You are welcome 😀
Hello sir nice tutorial. I am using card layout and wanted to give some background color. It works for above level 21 but doesnt works fine for the below ones. I am using both properties android:background=”@color/ darkgreen” android:cardBackgroundColor=”@color/darkgreen”. Any help @Ravi Tamada? Thanks.
If it’s not working, place another layout (Ex: LinearLayout) inside cardview and give background color to that layout. If you want to get the ripple effect on the card, use
android:foreground="?attr:selectableItemBackground"
for the layout added.hello Ravi..
Can you let me know how to add Click Listener on Image which are showing using cardview and recycleview..
You have to write click listener in adapter class and send the callback to activity via interface.
Try the below code.
package info.androidhive.cardview;
import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import java.util.List;
/**
* Created by Ravi Tamada on 18/05/16.
*/
public class AlbumsAdapter extends RecyclerView.Adapter {
private Context mContext;
private List albumList;
private AlbumsAdapterListener listener;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title, count;
public ImageView thumbnail, overflow;
public CardView cardView;
public MyViewHolder(View view) {
super(view);
title = view.findViewById(R.id.title);
count = view.findViewById(R.id.count);
thumbnail = view.findViewById(R.id.thumbnail);
overflow = view.findViewById(R.id.overflow);
cardView = view.findViewById(R.id.card_view);
}
}
public AlbumsAdapter(Context mContext, List albumList, AlbumsAdapterListener listener) {
this.mContext = mContext;
this.albumList = albumList;
this.listener = listener;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.album_card, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
Album album = albumList.get(position);
holder.title.setText(album.getName());
holder.count.setText(album.getNumOfSongs() + ” songs”);
// loading album cover using Glide library
Glide.with(mContext).load(album.getThumbnail()).into(holder.thumbnail);
holder.overflow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showPopupMenu(holder.overflow, position);
}
});
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onCardSelected(position, holder.thumbnail);
}
});
holder.thumbnail.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.onCardSelected(position, holder.thumbnail);
}
});
}
/**
* Showing popup menu when tapping on 3 dots
*/
private void showPopupMenu(View view, int position) {
// inflate menu
PopupMenu popup = new PopupMenu(mContext, view);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.menu_album, popup.getMenu());
popup.setOnMenuItemClickListener(new MyMenuItemClickListener(position));
popup.show();
}
/**
* Click listener for popup menu items
*/
class MyMenuItemClickListener implements PopupMenu.OnMenuItemClickListener {
int position;
public MyMenuItemClickListener(int position) {
this.position = position;
}
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.action_add_favourite:
listener.onAddToFavoriteSelected(position);
return true;
case R.id.action_play_next:
listener.onPlayNextSelected(position);
return true;
default:
}
return false;
}
}
@Override
public int getItemCount() {
return albumList.size();
}
public interface AlbumsAdapterListener {
void onAddToFavoriteSelected(int position);
void onPlayNextSelected(int position);
void onCardSelected(int position, ImageView thumbnail);
}
}
ok ..but where you define cardView = view.findViewById(R.id.card_view in your activity file and
in void onCardSelected(int position, ImageView thumbnail how we know that which image is clicked and what action should be perform on that..
Hi Ravi! thank you for the tutorial, but my scrolling isn’t smooth, can i ask why?
Disable nested scrolling on recyclerview if you are using NestedScrollView.
recyclerView.setNestedScrollingEnabled(false);
@Ravi Tamada:disqus Sir aap Best ho..!! Thankyou Androidhive
send me compete geofence source code in android,when i am going some places notify alarm
Thanks for great tutorial. Could you please tell me how this code would behave in landscape mode? how can I show 3 or more columns based on device width in landscape mode?
Hi,
Thanks for the awesome tutorial, I would like to ask you how to add click listener to each album and open new activity?
Add click event in adapter class and use interface to send callback to activity
What is glide and I cant add glide in my application how to use it?
Read this
https://www.androidhive.info/2016/04/android-glide-image-library-building-image-gallery-app/
once I run the apk its opening and closing suddenly what may be the possible error.I have used ur source code only.?
Check the LogCat for errors.
what to write in onCardSelected so that for each card a different activity will open when clicked.please help
Pls check the featured comment below for full code.
sir,i want it to pass a intent when clicked on card at position[0] to a activity and when clicked at position[2] to another activity,i have tried the featured code but i think it needs some changes according to my need.please help.
I clicked download and now the code is downloaded 46,500 times. Good Work Android Hive. <3 you.
Thank You. There are other downloads which are more than 3Lakhs 😀
Really helpful code. Thank you! Just one question. Why do you use Glide to load the images instead of just using setImageResource() on the ImageView?
setImageResource takes an image from the project’s drawable folder. As the image is there on Internet, we need to use Glide to load the images.
OK, thanks. It just seems you’re using drawables in your prepareAlbums method.
Oh I see. I remember using Glide because of below reason.
because my view is listview, adapter must be use glide for all getView, prevent image show on wrong position.
https://github.com/bumptech/glide/issues/588#issuecomment-132875295
Set NoActionBar theme for this activity in manifest file or remove the AppBar / Toolbar from the activity layout.
Thank you I solved the problem by following your advice (Set NoActionBar theme for this activity in manifest file )
Great.
Can I get your email address i would like to ask some questions.
You can ask here https://ask.androidhive.info
Hi Ravi, I just want to add functionality to each and every Card view differently. Means If I click on first Card View, a song will play and on the Sec card view, will play another. How can I do so?
Do you have an activity that will play a song?
hi sir and so much thanks for this great material design tutorial
i have a question and that is how can we show a spicific folder contents in card views?
for example folder named pictures in sd card
any help wil greatly appreciated
You can create an activity that will read pictures of a folder from sd card. On clicking the CardView, you can pass the folder path of sd card to this activity and display the images.
hey sir sorry for annoyance but im new in android studio and don’t know much about strings, if its simple can you please show me how with code?
again thanks in advance
What do you want to know about strings? You mean strings.xml?
no no i want what i wanted before show contents from a folder (for example pictures,etc) in card view
as im a begginer so i couldnt done what you told about listing contents in a activity and pass the folder path
can you show me with code?
ps; i though we have to define the path using string that’s because i said about strings
Hi Ravi. I wanted to know a way to make each card completely fill the horizontal space rather than two cards sharing the space. How can that be done? Thanks in advance.
In the MainActivity,
GridLayoutManager(this, 2)
is used as Layout Manager. Here 2 is number of columns. You can make it 1 or useLinearLayout
manager instead. You also need to adjust your ImageView aspect ratio.sir hum tabbed activity k sath kese jin kr skte hain isko.
How can i get to another activity if i click for example the item in onMenuItemClickListener? Thanks
Do you know the code to launch an activity?
yes. but it has error…
Intent intent = new Intent(AlbumsAdapter.this, Download.class);
startActivity(intent);
I think what keeping it error is that my extends recyclerview adapter and appcompatactivity is not compatible
Instead of
AlbumsAdapter.this
, usemContext
.Intent intent = new Intent(mContext, Download.class);
But its not opening the Download.class . Im new to android. please help me
🙁
I use this. But it has error. The app keeps on stopping…
intent = new Intent(mContext, Web.class);
mContext.startActivity(intent);
What was the error when it crashed?
Open app again…
Connect your device using USB, open LogCat in Android Studio. When the app crashes, the error will be printed in LogCat.
This is not the error but don’t worry you will learn on the go. Explore more about app debugging and LogCat.
Ok. Appreciate it man. Thanks so much. 🙂
You are welcome. Let me know once you solve the problem.
Can you show me how?. Thanks
If you want to launch another activity by clicking the image on the card, do you handle the onclicklister from the adapter class or on the mainactivity class?
You can do it in both ways. The click listener assigned in adapter when you want to detect click on different elements. Ex: text, image etc., But if you want to detect the just the row click, writing the listener in main activity is good choice.
hello @Ravi Tamada:disqus when i run the app it said that card view has stoped why ???!!!1
Check the LogCat for errors while the app is crashing.
Good day @Ravi Tamada:disqus . Unfortunately, I still cant find to when i click the item in the 3 dots i cant go to another page or another activity. Please help
Paste your Adapter class code.
Not the screenshot. Anyways try the below instead of toast.
Intent intent = new Intent(mContext, YourActivity.class);
mContext.startActivity(intent);
still not working. :'(
I’m trying to implement on click listeners for each card view which shows different activity. but it is showing the same activity.
This is what i have tried to implement.
public MyViewHolder(View v) {
super(v);
view = v;
title = (TextView) view.findViewById(R.id.title);
count = (TextView) view.findViewById(R.id.count);
thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
view.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
Intent intent = new Intent(view.getContext(),FirstActivity.class);
view.getContext().startActivity(intent);
}
});
}
Please explain how to show SecondActivity on clicking second cardview.
Hi RK
The way you are doing currently is correct. Normally all the click events will launch the same activity by passing necessary data via intents. In this case, an id or name (some unique identification of each card) will be sent to next activity. You need to take appropriate action depending on the id.
The way you are thinking (creating new activity for each card) is wrong as you shouldn’t create 100 activities if there are 100 cards.
Thanks for replying .
Actually I sorted it out yesterday only by using switch statements cases to open activities.
But the way using id will save more data in app.
It was great tutorial and anyways.
I’ll try to post my code here which worked perfectly for me.
Okay.
@Ravi Tamada:disqus Can you please Help me about this problem? Am I have to use Switch Case?
Do the following.
1. When a card is selected, send the file name to another activity.
2. Create an activity which plays a song. The song file name will be read from Intent sent from cards grid activity.
Refer this article to know how to send data to another activity via intents.
https://www.androidhive.info/2011/10/android-listview-tutorial/
Ok done, but I can not play different songs, Just one song is playing when I select any card? How Can I play different songs from Different Cards?
Sorry to say , your code is so messed up, i keep having the error :
Attempt to invoke virtual method ‘void android.support.design.widget.CollapsingToolbarLayout.setTitle(java.lang.CharSequence)’ on a null object reference
Why u wanna make the toolbar so complex ? any messed up with everything, i tried to change the toolbar, try to remove it, it just cant work. Please next time check ur code before upload it up !
Sorry its works now , my fault , my stupid mistakes, thanks alot for your code, im so sorry, i apologize , you done a great job !!!
Don’t worry 🙂
Happy coding.
Hi, Thank you for all the tutorials.
I tried to use what’s in this to to update my recyclerview. It worked, but i want to change number of items per row. How to do that, as you give for example “2” as spancount to the GridLayoutManager ? Thanks again
Yes 2 is the number of columns. You can change that number to whatever number of items you want.
@James
Implement your OnClickListeners in class MyViewHolder()
Let’s Assume you have two CardViews which opens has different activities, use this code which worked for me.
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (getAdapterPosition()) {
case 0:
Intent firstIntent= new
Intent(view.getContext(),com.example.android.YourApp.FirstActivity.class);
view.getContext().startActivity(firstIntent);
break;
case 1:
Intent secondIntent = new
Intent(view.getContext(),com.example.android.YourApp.SecondActivity.class);
view.getContext().startActivity(secondIntent);
break;
Similarly you can increase number of cases based on number of cards you use.
You can also achieve this by using id’s for different acivities.
Could you show more code please? thank you very much
hey man,i tried your code but nothing happens when i click a card view.What to do now,need help.
Hi, i just want to ask how can i get my app like these? When clicked install then it will be installed and put in another activity. Thanks
Ravi thanks for your tutorial it helps me a lot. How it could be if the image, album name and no of song are retrieved from firebase. please help me Ravi it helps me a lot for my final year project
You can firebase UI project to bridge RecyclerView with firebase database. Have a look at here
https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md#using-the-firebaserecycleradapter
hello and thanks for great tut one question, how to load all device images into this app instead of drawable images?
What do you meant by into app? If you kept them inside drawables, they will be inside app only.
i want to use this sample and load gallery images into recyclerview not from drawable folder
Hello again, Thank you for this tutorial. I have a problem with the elevation and radius not working for the cardview. It’s like the attributes add no effect. Dont know i tried many things but yet not solved. Thanks again.
Have you tried adding margin to CardView? Because elevation appears outer side of Card.
Yes i did, and it worked. Thanks
Great 🙂
Hello, Ravi.
I can’t run App.
It shows render problem:
Failed to find style with 17170445.
Could you tell me what does it mean?
Thanks.
Could you paste the entire error report?
When I start the app it shows a white screen and then stops. The only problem I came across is:
Render problem ( in activity_main)
Failed to find style with 17170445
Tip: Try to refresh the layout.
I too got the same error!
plz help with that!!
Try Cleaning and Re-building your project.
Hey, nice !!!!
I want to know about the modifications that will need to implement this program as a fragment?
Hi sir.,
how can i put onitemclickListener this file.?
i want put itemClickListener to move another one activity.,
when is it possible tell me how.,
it’ll be useful to me grow..
Check the comments below. There is a Featured Comment by me. It has all the code needed for the click event.
thank you for your reply sir.,
its very useful..
You are welcome 🙂
sir.,
today i asked one doubt in your comment box.,
kindly shares your valuable codes.,
thanks in advance.,
im a new comer in android developing so when you help this time its may useful to me of all time.,
thanking you..
I think, I replied already.
this is my recent doubt sir.,
i didnt receive ur reply.,
kindly see my comment and give me a support with ur code.,
thanks in advance..
What is the height of inflate card layout? It should be wrap_content.
oh okay, that helped me,.. thank u
You are welcome 🙂
Hi Ravi!Tnq for tutorial!in my app there are multiple Recyclerview that fill from server Dynamically!Now ,I’ve put a separate array list for each Recyclerview !my question is How to i use one array list for all Recyclerview!
like horizantal Recyclerview googleplay! 🙂
If you have multiple RecyclerViews in a single View, I suggest go ahead with Fragments. In this way, you will more control over the individual modules and it will be easier to maintain the code.
Can you please help i get error on this line after applying clicklistener
adapter = new AlbumsAdapter(this, albumList);
What is the error? Maybe replace
this
with MainActivity.javaError:(44, 19) error: constructor AlbumsAdapter in class AlbumsAdapter cannot be applied to given types;
required: Context,List,AlbumsAdapterListener
found: MainActivity,List
reason: actual and formal argument lists differ in length
Well, you can see AlbumsAdapter takes three arguments, but you are passing just two. Pass
this
as third argument and implement your MainActivity class from AlbumsAdapterListener.adapter = new AlbumsAdapter(this, albumList, this);
thanks
No, you have to maintain multiple array lists. Each fragment will have its own RecyclerView and an array list. From the screenshot, top Games section will be a Fragment with RecyclerView and array list. Likewise the You might like section. The inflated layout used in adapter class is same for all the RecyclerVIews.
Hello sir.,
im a beginner for android app development.,
i learn a lot from your projects.,
now i want to know one doubt.,
How to add setOnClickListener for each item in CardView
and i want to add webview for this project when one card clicked it will pass the given url link and shows what its get.,
almost i create the code for this url links on javascript.,
now i want to know How to add setOnClickListener for each item in CardView and how can i pass url links in each cards while click the cards.,
each links are different also.,
kindly clear my doubt.,
and if u send the code for it.,it’ll very useful to me.,
thanking you..
Are you able to detect the click even using the code (in the featured comment) provided?
yeah but i cant understand how to put webview content in this code.,
when i did it.,it doesnt shows any error in logcat but the app stoped its working and didnt work properly.,
thats why i asking to u.,
last code teach me how works click listener in cards.,but as a beginner i want to know to add onclicklistener for each cards.,and how can i put URL link for each cards.,thats all sir.,hope u understand my position..
You need tell me how you added the WebView and what is the error.
This is my error page and my modification in ur code sir.,
Check LogCat. There will be error when the app crashes.
it does’nt shows any error sir.,when i remove these codes from there.,the problems are solved.,
i hope u identify my needs so if possible kindly shares your code for my needs..
You can create another activity which will have a WebView to display an url. When a card is selected, pass the url to this activity and open the page.
Here is the tutorial about WebView. You can directly add BrowserActivity in your project.
https://www.androidhive.info/2016/12/android-working-with-webview-building-a-simple-in-app-browser/
thank u for your reply and great support.,
thank u for your responsible reply sir.,
but my app will be like hybrid.,which was added with java script file too.,so when i create an activity for each card how can i add a link while click the card.,this was my vision only when your way of solution (reply) is possible.,help me to find the suitable way.,my previous app also same as like this but the url link passed by navigation drawer so i handled it easy.,but this time i faced this cardview so i stand alone to face this sir.,
Keep your project in git and share with me. I can have a look. This way I can’t help much as it’s not giving me full picture.
sure sir.,this is the link-https://github.com/manie-b/CVV
Thanks in Advance
Can u post the source code files
Download button is there at the beginning of the article.
Hello Sir,

when i add dependencies for cardview in gradle file error occurs..
can you please help me to solve the error..
The version should be 26.1.0 matching the other supported libraries.
okay.. Thank you..
Sir I want to send the images of card view to next activity using intent what should I do in putextra??
How the image in CardView is displayed. From http url?
sir I am using your project and I want the images used in this project’s card view to next activity.
he hasn’t used glide library from Google to display the image
If the image from url, then how to do it sir?
Hi Indra
The way you are writing click listener is wrong. You can assign a click listen on to RecyclerView directly, instead of writing it individually the for the layout item.
Read this article. I have written how to add click listener to RecyclerView (6. Adding RecyclerView Item Click Listener)
https://www.androidhive.info/2016/01/android-working-with-recycler-view/
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
Movie movie = movieList.get(position);
Toast.makeText(getApplicationContext(), movie.getTitle() + " is selected!", Toast.LENGTH_SHORT).show();
}
@Override
public void onLongClick(View view, int position) {
}
}));
Thanks very much Sir Ravi, I will try your suggestion.. Thanks thanks a lot 🙂
Do let me know if you have a problem.
Cheers!
Sir Ravi, it’s working for my code 🙂 Thanks so much Sir Ravi. Keep sharing knowlegde. Sharing Knowledge = new more Knowledge {for you from GOD} 😉
Cheers!
Happy Coding 🙂
Hi Sir.,i want to ask one small question from this card view example.,that was how can i create 3 cards in a row.?almost two cards in your tutorials.,and i want to change my requirement on it.,help me to done it.,thanks in advance..
hello,
you mentioned in your tutorial that two layouts are bring created when the project gets created
but in my case only one layout is present i.,e activity_main.xml
and content_main.xml is absent
i am using android studio 3.0.1
and one more query was
you have used collapsing toolbar
i that the layout which disappears as soon as we scroll to the bottom of the list
looking forward for your reply
thanks you very much for the tutorial
they helped me clear some concepts 😉
Nice article it worked for me thanks man. how can we add on click listener on cards.
The complete code of adapter can be found in the comment section. See the featured comment by me.
Where are the images for this project?