Welcome to the Recycler-world where our views are card-based(I): A comprehensive explanation to using RecyclerView in your Android app

Ayokunle Paul
CodebagNG
Published in
8 min readAug 14, 2017
CodebagNG- Android

It’s no news for every Android developer that the Google Android team are working their asses off to make Android applications look cool and less memory consuming. RecyclerView and CardView does exactly this.

Voila, Material design was introduced to Android as a support library. I don’t need to explain what a support library is now, do I? In this article, we’ll be building a Material Design based app.

N.B.: Creating a RecyclerView view is similar to creating a custom ListView.

Here’s what our final app will look like.

MaterialDesign full app.

Requirements: Android Studio, Fair Knowledge of Android Programming and maybe one or two cups of coffee.

Let’s get started…

Step 1: Create a new project

Enter project name
Enter necessary details
Let’s stick with Empty activity

Once the project finishes building, there’s one more thing to do before we start coding. We need to add the necessary dependencies our project. This will give us access to the RecyclerView and CardView library.

Application level build.gradle file

To do this, open the app level build.gradle file and add the dependencies,

compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.android.support:cardview-v7:25.3.1'

or go to the project structure page. Press Ctrl + Alt + Shift +S to go there from your current page. Go to the app module and click on the dependency tab. Click on the add button then click on library dependency. Search for com.android.support:recyclerview… and com.android.support:cardview… and add them. Click OK and wait for your project to rebuild.

Adding RecyclerView and CardView

Now we are set up and ready to code.

Go to your main layout file(mine’s activity_main.xml) and modify it to the one in the picture below.

activity_main.xml

Before we proceed further, let me give a layman’s explanation of the relationship between RecyclerView and CardView. A RecyclerView is like a list containing multiple items and each item of this list is a CardView.

Therefore, to customize the look and feel of our RecyclerView, all that’s needed is to tweak our CardView(since it’s the view carrying the items in the RecyclerView).

But… How do we go about this? Good question. Hop along!!!

Step 2: Create a custom layout file.

The next thing is to create a custom layout file. I have created a layout file with the name card_view_item.xml(you can name yours anything). Modify the xml layout to the one in the picture below.

card_view_item.xml file
Second part of card_view_item.xml file

I won’t be explaining what each of the attributes mean, they’re pretty straight forward. One thing that should noted is the card_view schema. Be sure to import the right one.

xmlns:card_view="http://schemas.android.com/apk/res-auto"

From our layout file, it’s evident that our cardview contains 4 main attributes.

  1. Contact image
  2. Contact name
  3. Contact email
  4. Contact phone

This means each of the item displayed must contain these four attributes. The step is to give “this item” a name. All we have done so far is create a CardView powered layout that contains our item’s attributes(picture, name e.t.c.).

Step 3: Create custom item class.

Now that we are done with our UI, let’s delve into the back-end and get our hands wet with some Java codes. But first, we need to create a custom class.

Custom class.

Now that we’re done with that, edit your file to look like the one in the picture below.

Modified Contact.java file

All we have done here is declare variables that will store the information of each contact in parallel(In parallel means, each contact is independent of the other).

  1. int id: This variable helps store the resourceId of our contact’s image. This is quite easy to understand, if you scroll up to one of the images above, you’ll notice that my drawable resource folder contains 5 new items(pictures). Those are the pictures I’ll be working with for this project. I suggest you import yours too. So, all our id variable does is to save the android generated resource identity(resourceId) for the contact and in case we need it, there’s a getter method(getId()) that will deliver it to our doorstep in no time.
  2. String contactName: A string containing the reference to our Contact’s name and a getter method (getContactName()) to deliver it for us in no time.
  3. String contactPhone and contactEmail: They are exactly like String contactName.

It’s worth stating here the similarity between my variable names and their functions. This necessity of this cannot be overemphasized.

We are done with this part, so onto the next step.

Step 4: Create a custom adapter

A little advice for those relatively new to Android, if all these seem overwhelming already… just take a few minutes to relax. You know why?Because this part is quite tricky and technical.

That been said, let’s get the ball kicking(or how do they say it?).

We’ll start off by creating a new class and call it CardViewAdapter.

CardViewAdapter.java file

Inside this class, create a new inner static class that extends RecyclerView.ViewHolder class.

Check the image below…

Create inner class CardViewHolder

This class does exactly what it’s name says, holds our views. Remember the items we created in our card_view_item.xml file? Yes. That one. It is the CardViewHolder class that will hold them for us. How will it do this?

Let’s find out. Shall we?

Check the picture below and modify your code appropriately.

Modified CardViewHolder class

Looks pretty simple, right?

All we’ve done is pass some id’s to a bunch of views, right? Yes! You got it. I’ll give a detailed explanation later.

Now modify you main class(CardViewAdapter) to extend RecyclerView.Adapter<CardViewAdapter.CardViewHolder> class, implement the necessary methods.

Here’s what I have on my end.

CardViewAdapter after extending RecyclerView.Adapter<CardViewAdapter.CardViewHolder> class

Looks pretty straightforward, right? I don’t think so too.

Remember, I warned you about this part being tricky… We’re just getting started.

Next, let’s create a constructor that will enable our CardViewAdapter class to state it’s demands from any class that wishes to call it.

Check the image below and make the necessary modifications…

So, the constructor has been added and it take’s two parameters. A context instance and an ArrayList<Contact> instance that contains each contact we wish to display. These two parameters are then passed to their respective class parameters. So let’s take a good look at everything we’ve done so far and how it all works.

  1. When you instantiate the CardViewAdapter class
CardViewAdapter cardViewAdapter = new CardViewAdapter(context, contacts);

the constructor initializes the necessary variables(context, contacts) so the won’t be seen by others as null. Don’t forget this initialization is triggered by the class performing the instantiation.

2.After this, the onCreateCardHolder(ViewGroup parent, int viewType) method gets called. If we take a cursory look at our card_view_item.xml file, we’ll see that the parent view is a CardView. That is exactly why we are inflating this layout and passing it to CardView instance.

LayoutInflater.from(context).inflate(R.layout.card_view_item, parent, false);

The above code returns a View(Every visible android object inherits from this class) class object which is downcasted to a CardView.

CardView cardView = (CardView)
LayoutInflater.from(context).inflate(R.layout.card_view_item, parent, false);

Wait a second…

All we did was pass the root view of our card_view_item.xml to CardView instance. What about the children views?

Your guess is as good as mine… That is what the next line is for.

new CardViewHolder(cardView);

This line triggers the initialization in our CardViewHolder class.

contactImage = (ImageView)cardView.findViewById(R.id.contact_image);
contactName = (TextView)cardView.findViewById(R.id.contact_name);
contactPhone = (TextView)cardView.findViewById(R.id.contact_phone);
contactEmail = (TextView)cardView.findViewById(R.id.contact_email);

3. After the command has been executed, the control flow enters the onBindViewHolder method. Remember the return type of onCreateViewHolder() holder is a CardViewHolder. Whatever is returned from this method is passed directly to the onBindViewHolder() method as it’s first parameter. But what if you have more than one contact. How would it bind everything all together?

Good question. The answer is simple. Look at the method again, it contains a second integer parameter. This parameter is the returned value of the getItemCount() method. If the value of the parameter is n, then onBindViewHolder() loops n times. Do you get?

So, let’s go and modify our onBindViewHolder() method. Check the image below and modify your code accordingly.

Final update

Now we are done with the CardViewAdapter class. Here’s a brief summary of how the control flows again.

Constructor →onCreateViewHolder() →CardViewHolder() →onBindViewHolder()

Step 5: Modify your main activity and run the app

Now, let’s move to the MainActivity.java file and do some editing.

Here’s an updated image of everything.

All I did was initialize the RecyclerView , CardViewAdapter and ArrayList<Contact>. And that’s it. We now have a MaterialDesign, more like a RecyclerView, powered app. To change your layout orientation from Linear to Grid, just change

recyclerView.setLayoutManager(new LinearLayoutManager(this));

to

recyclerView.setLayoutManager(new GridLayoutManager(this, 2));

But to use this line, you have to modify your ItemDecorator and edit your xml file seperately. That won’t be covered in this tutorial. One last thing, you might be asking why you should use RecyclerView instead of the less stressful ListView.

Firstly, compared to ListViews, RecyclerViews are super super flexible. This may not be apparent for relatively small-scale applications but it becomes more evident when you have a robust project.

Secondly, animating a RecyclerView is much more robust and cool.

Most importantly, memory consumption is minimal with RecyclerViews.

And that will be all. There’s a second part to this tutorial. Stay synchronized().

Let me know what you think by dropping your comment(s). Or reach me at pauleipeks@gmail.com

--

--