Note:Â If you are using Kotlin Programming Language, please refer to the latest article on How to Implement RecyclerView using Kotlin Programming Language.
RecyclerViews and CardViews are currently the most popularly used elements replacing the listviews and GridViews. In this tutorial, we are going to discuss about Android RecyclerView and CardView tutorial using New Android Studio.
What is a RecyclerView?:
Recyclerview in Android is the most recent and advanced version of Listview. The main Advantage of RecyclerView over ListView can be seen from the following link. Google’s I/O Conference explains why Google has moved from ListView to RecyclerView.
In this Android RecyclerView and CardView tutorial, we are going to discuss about creating a list of Cards using RecyclerView and CardView.
[adinserter block=”2″]
What is a CardView?:
Cardview is the latest element added to Android’s Material Design which extends FrameLayout class. Using Cardview and RecyclerView, you can display list items in beautiful cards which can have shadows and Rounded Corners. You can refer to Developer’s Documentation of CardView here.
Android RecyclerView and CardView tutorial:
The following video demonstrates what we are about to create in this tutorial:
The complete code for the Project Android RecyclerVIew and CardView Tutorial is available below this article.
Let us start creating our project on Android RecyclerView and CardView Tutorial.
-
Adding RecyclerView and CardView to the Project:
[adinserter block=”2″]
To add recyclerview and CardView to the project, we need to add the following dependencies to our app’s build.gradle file:
//adding a recyclerview compile 'com.android.support:recyclerview-v7:23.4.0' //adding a cardview compile 'com.android.support:cardview-v7:23.4.0'
a. Adding a RecyclerView:
A RecyclerView can be added to any layout by using the following code:
<!-- A RecyclerView with some commonly used attributes --> <android.support.v7.widget.RecyclerView android:id="@+id/my_recycler_view" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent"/>
Here, I’ve added the RecyclerView to my activity_main.xml file with the code below:
[widget id=”text-3″]
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:background="@color/background" tools:context="com.coderefer.recyclerviewtutorial.MainActivity"> <!-- A RecyclerView with some commonly used attributes --> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height = "match_parent"/> </RelativeLayout>
Now open res > values > colors.xml and add the following color codes to the file:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#9C27B0</color> <color name="colorPrimaryDark">#7B1FA2</color> <color name="colorAccent">#FE3F80</color> <color name="textPrimary">#212121</color> <color name="textSecondary">#727272</color> <color name="white">#fff</color> <color name="background">#dae2e2e2</color> </resources>
b. Adding a CardView:
A CardView can be added to our XML file using the following code:
<!-- A CardView that contains a TextView --> <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="200dp" android:layout_height="200dp" card_view:cardCornerRadius="4dp"> <ImageView android:id="@+id/iv_info_image " android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v7.widget.CardView>
2. Creating a List Item:
Now we shall create a list item for our RecyclerView so that we can populate the required data into RecyclerView.
[adinserter block=”1″]
Here is my XML layout for the list item which I named it as song_list_item.xml with the following code:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="10dp" android:paddingLeft="2dp" android:paddingRight="2dp" android:paddingTop="10dp"> <!-- A CardView that contains another views --> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:clickable="true" android:foreground="?android:attr/selectableItemBackground" card_view:cardCornerRadius="2dp" card_view:cardUseCompatPadding="true"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/iv_album_cover" android:layout_width="match_parent" android:layout_height="150dp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:clickable="true" android:foreground="?android:attr/selectableItemBackground" android:scaleType="centerCrop" android:src="@drawable/pillow_talk" /> <TextView android:id="@+id/tv_song_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="Pillow Talk" android:textAllCaps="true" android:layout_below="@id/iv_album_cover" android:textColor="@color/colorAccent" android:textSize="18sp" android:textStyle="bold"/> <LinearLayout android:id="@+id/linearLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="3dp" android:orientation="horizontal"> </LinearLayout> <TextView android:id="@+id/tv_singer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Zayn" android:textColor="@color/textSecondary" android:textSize="16sp" android:textStyle="bold|italic" android:layout_below="@id/tv_song_name" android:layout_marginTop="10dp" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> <TextView android:id="@+id/tv_year" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:text="2016" android:textColor="@color/textSecondary" android:textSize="16sp" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/tv_rank" android:layout_toLeftOf="@+id/tv_rank" android:layout_toStartOf="@+id/tv_rank" android:text="# " android:textColor="@color/white" android:textSize="20sp" android:textStyle="italic" /> <TextView android:id="@+id/tv_rank" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentRight="true" android:textColor="@color/white" android:text="1" android:textSize="20sp" android:textStyle="italic" /> </RelativeLayout> </android.support.v7.widget.CardView> </RelativeLayout>
All the drawables and remaining files used in this project can be downloaded from the link above.
3. Creating a Model:
[adinserter block=”2″]
Next we will create a model so that we can get and set the required values.
In this tutorial, I’ve created a Model class which I named it as Song.java which consists of the following code:
package com.coderefer.recyclerviewtutorial.models; /** * Created by vamsi on 27-Apr-16. */ public class Song { private String name, singer,year; private int pic,rank; public Song(String name, String singer, int rank, int pic){ this.name = name; this.singer = singer; this.rank = rank; this.pic = pic; } public int getRank() { return rank; } public void setRank(int rank) { this.rank = rank; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPic() { return pic; } public void setPic(int pic) { this.pic = pic; } public String getSinger() { return singer; } public void setSinger(String singer) { this.singer = singer; } public String getYear() { return year; } public void setYear(String year) { this.year = year; } }
4. Creating an Adapter:
Let us define a custom adapter for our Recyclerview. Here I named the class as SongAdapter.java. The code is commented wherever it is necessary. A ViewHolder is used in recyclerview where as it is optional in ListView. Here onCreateViewHolder() is used to create Views and onBindViewHolder() is used to bind the views according to the position.
[widget id=”text-3″]
package com.coderefer.recyclerviewtutorial.adapters; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.coderefer.recyclerviewtutorial.R; import com.coderefer.recyclerviewtutorial.models.Song; import java.util.ArrayList; import java.util.List; import java.util.zip.Inflater; /** * Created by vamsi on 06-May-16 for android recyclerview and cardview tutorial */ public class SongAdapter extends RecyclerView.Adapter<SongAdapter.ViewHolder> { private List<Song> songList; //Provide a reference to the views for each data item //Complex data items may need more than one view per item, and //you provide access to all the views for a data item in a view holder public static class ViewHolder extends RecyclerView.ViewHolder{ //each data item is just a string in this case public TextView tvRank,tvSongName,tvSinger,tvYear; public ImageView ivAlbumCover; public ViewHolder(View v) { super(v); tvRank = (TextView)v.findViewById(R.id.tv_rank); tvSongName = (TextView) v.findViewById(R.id.tv_song_name); tvSinger = (TextView) v.findViewById(R.id.tv_singer); tvYear = (TextView) v.findViewById(R.id.tv_year); ivAlbumCover = (ImageView) v.findViewById(R.id.iv_album_cover); } } //Provide a suitable constructor public SongAdapter(List<Song> songList){ this.songList = songList; } //Create new views (invoked by the layout manager) @Override public SongAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //Creating a new view View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.song_list_item,parent,false); //set the view's size, margins, paddings and layout parameters ViewHolder vh = new ViewHolder(v); return vh; } //Replace the contents of a view (invoked by the layout manager @Override public void onBindViewHolder(SongAdapter.ViewHolder holder, int position) { // - get element from arraylist at this position // - replace the contents of the view with that element Song song = songList.get(position); holder.tvRank.setText(String.valueOf(song.getRank())); holder.tvSongName.setText(song.getName()); holder.tvSinger.setText(song.getSinger()); holder.tvYear.setText(song.getYear()); holder.ivAlbumCover.setImageResource(song.getPic()); holder.tvYear.setText("2016"); } @Override public int getItemCount() { return songList.size(); } }
5. Changing the Activity’s Code:
Now we add the following code to our MainActivity.java so that we will get and set the data to a model and set the adapter to our recyclerview.
package com.coderefer.recyclerviewtutorial; import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.View; import android.widget.Toast; import com.coderefer.recyclerviewtutorial.adapters.SongAdapter; import com.coderefer.recyclerviewtutorial.models.Song; import java.util.ArrayList; import java.util.List; /** * Created by vamsi on 4-May-16 for android recyclerview and cardview tutorial */ public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private RecyclerView.LayoutManager mLayoutManager; private List<Song> songList; private SongAdapter songAdapter; String[] names = {"I Took A Pill In Ibiza", "7 Years", "Pillow Talk", "Work From Home", "Never Forget You", "Don't Let Me Down", "Love Yourself", "Me, Myself & I", "Cake By The Ocean", "Dangerous Woman", "My House", "Stressed Out", "One Dance", "Middle", "No"}; String[] singers = {"Mike Posner", "Lukas Graham", "Zayn", "Fifth Harmony", "Zara Larsson & MNEK", "The Chainsmokers", "Justin Bieber", "G-Eazy x Bebe Rexha", "DNCE", "Ariana Grande", "Flo Rida", "Twenty one Pilots", "Drake", "DJ Snake", "Meghan Trainer"}; int[] pics = { R.drawable.took_a_pill, R.drawable.seven_years, R.drawable.pillow_talk, R.drawable.work, R.drawable.never_forget_you, R.drawable.dont_let_me_down, R.drawable.love_yourself, R.drawable.me_myself_and_i, R.drawable.cake_by_the_ocean, R.drawable.dangerous_woman, R.drawable.my_house_florida, R.drawable.stressed_out, R.drawable.one_dance, R.drawable.middle, R.drawable.no}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); //Use this setting to improve performance if you know that changes in //the content do not change the layout size of the RecyclerView if (mRecyclerView != null) { mRecyclerView.setHasFixedSize(true); } // //using a linear layout manager mLayoutManager = new LinearLayoutManager(this); /* use this in case of gridlayoutmanager mLayoutManager = new GridLayoutManager(this,2); */ /* use this in case of Staggered GridLayoutManager */ // mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mLayoutManager); //intializing an arraylist called songlist songList = new ArrayList<>(); //adding data from arrays to songlist for (int i = 0; i < names.length; i++) { Song song = new Song(names[i], singers[i], i + 1, pics[i]); songList.add(song); } //initializing adapter songAdapter = new SongAdapter(songList); //specifying an adapter to access data, create views and replace the content mRecyclerView.setAdapter(songAdapter); songAdapter.notifyDataSetChanged(); } }
6. Implementing Click Listener for RecyclerView Item:
[adinserter block=”1″]
RecyclerView does not have onItemClickListener() unlike ListView. So we need to add a custom class which extends RecyclerView.OnItemTouchListener().
Here I created a new class and named it as RecyclerItemClickListener and added the following code to it:
package com.coderefer.recyclerviewtutorial; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; /** * Created by vamsi on 20-May-16 for android recyclerview and cardview tutorial */ public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener { private OnItemClickListener mListener; GestureDetector mGestureDetector; public interface OnItemClickListener{ public void onItemClick(View view, int position); } public RecyclerItemClickListener(Context context, OnItemClickListener listener) { mListener = listener; mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } }); } @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { View childView = rv.findChildViewUnder(e.getX(),e.getY()); if(childView != null && mListener != null && mGestureDetector.onTouchEvent(e)){ mListener.onItemClick(childView, rv.getChildAdapterPosition(childView)); return true; } return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } }
Next, we need to modify our android recyclerview and cardview tutorial’s MainActivity.java file so that the click will be detected. We write the following code to it in onCreate() method:
mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Toast.makeText(MainActivity.this, "Card at " + position + " is clicked", Toast.LENGTH_SHORT).show(); } }));
Now I am creating Options Menu to display Various kinds of Views available in RecyclerView Android. I’ve added the following methods to the MainActivity.java file:
[adinserter block=”2″]
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.main_menu, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.item_grid: //use this in case of gridlayoutmanager; 2 indicates no. of columns mLayoutManager = new GridLayoutManager(this, 2); mRecyclerView.setLayoutManager(mLayoutManager); break; case R.id.item_staggered_grid: //use this in case of Staggered GridLayoutManager; 2 indicates no. of columns mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mLayoutManager); break; case R.id.item_horizontal: //horizontal linear layout mLayoutManager = new LinearLayoutManager(MainActivity.this,LinearLayoutManager.HORIZONTAL,false); mRecyclerView.setLayoutManager(mLayoutManager); break; } return super.onOptionsItemSelected(item); }
Now the modified MainActivity.java of our android recyclerview and cardview tutorial will look like:
package com.coderefer.recyclerviewtutorial; import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.Toast; import com.coderefer.recyclerviewtutorial.adapters.SongAdapter; import com.coderefer.recyclerviewtutorial.models.Song; import java.util.ArrayList; import java.util.List; /** * Created by vamsi on 4-May-16 for android recyclerview and cardview tutorial */ public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private RecyclerView.LayoutManager mLayoutManager; private List<Song> songList; private SongAdapter songAdapter; String[] names = {"I Took A Pill In Ibiza", "7 Years", "Pillow Talk", "Work From Home", "Never Forget You", "Don't Let Me Down", "Love Yourself", "Me, Myself & I", "Cake By The Ocean", "Dangerous Woman", "My House", "Stressed Out", "One Dance", "Middle", "No"}; String[] singers = {"Mike Posner", "Lukas Graham", "Zayn", "Fifth Harmony", "Zara Larsson & MNEK", "The Chainsmokers", "Justin Bieber", "G-Eazy x Bebe Rexha", "DNCE", "Ariana Grande", "Flo Rida", "Twenty one Pilots", "Drake", "DJ Snake", "Meghan Trainer"}; int[] pics = { R.drawable.took_a_pill, R.drawable.seven_years, R.drawable.pillow_talk, R.drawable.work, R.drawable.never_forget_you, R.drawable.dont_let_me_down, R.drawable.love_yourself, R.drawable.me_myself_and_i, R.drawable.cake_by_the_ocean, R.drawable.dangerous_woman, R.drawable.my_house_florida, R.drawable.stressed_out, R.drawable.one_dance, R.drawable.middle, R.drawable.no}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); //Use this setting to improve performance if you know that changes in //the content do not change the layout size of the RecyclerView if (mRecyclerView != null) { mRecyclerView.setHasFixedSize(true); } // //using a linear layout manager mLayoutManager = new LinearLayoutManager(this); // use this in case of gridlayoutmanager // mLayoutManager = new GridLayoutManager(this,2); // use this in case of Staggered GridLayoutManager // mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); //wiring up layoutmanager to our android recyclerview mRecyclerView.setLayoutManager(mLayoutManager); //intializing an arraylist called songlist songList = new ArrayList<>(); //adding data from arrays to songlist for (int i = 0; i < names.length; i++) { Song song = new Song(names[i], singers[i], i + 1, pics[i]); songList.add(song); } //initializing adapter songAdapter = new SongAdapter(songList); //specifying an adapter to access data, create views and replace the content mRecyclerView.setAdapter(songAdapter); songAdapter.notifyDataSetChanged(); mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Toast.makeText(MainActivity.this, "Card at " + position + " is clicked", Toast.LENGTH_SHORT).show(); } })); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.main_menu, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.item_grid: // use this in case of gridlayoutmanager, 2 indicates no. of columns mLayoutManager = new GridLayoutManager(this, 2); mRecyclerView.setLayoutManager(mLayoutManager); break; case R.id.item_staggered_grid: // use this in case of Staggered GridLayoutManager, 2 indicates no. of columns mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mLayoutManager); break; case R.id.item_horizontal: //horizontal linear layout mLayoutManager = new LinearLayoutManager(MainActivity.this,LinearLayoutManager.HORIZONTAL,false); mRecyclerView.setLayoutManager(mLayoutManager); break; } return super.onOptionsItemSelected(item); } }
The complete code for the Project Android RecyclerVIew and CardView Tutorial can be cloned/downloaded from the github repo link below:
[adinserter block=”1″]
nannayitttund
Great straight-forward tutorial: crisp, clear and helpful – simply the best I’ve found on the net. Thank you!
perfectly work ! thankyou so much