Making lists with Recyclerview

In my dev journey I came across lots of challenges, so I thought it would be really nice to give back to the community and create a series of tutorials. I'm gonna highlight some of the things that got me the most headaches at first.


RecyclerView

The best way to go

 

So you wanna make a list in your app, maybe just a simple grocery list or a more complicated one containing text, images and all the good stuff. What if you wanna get all that information from the cloud? There are many ways to do this, but I'm going to show you how to use the newest, and best of them. That would be the RecyclerView (I'm gonna assume you already know what views and layouts are).

It will seem really complicated at first, because by itself the RecyclerView needs a lot of elements to function but you'll soon realise it all works easily, and logically.


What you need

Let's get a bird's eye view of everything that we need at first. 

 

So you booted up good ol' Android Studio, created a new project, and now you have a layout file, called activity_main.xml and a Java file, called MainActivity. 

As the RecyclerView is a newer thing, or just because google literally forgot it launched it in 2014, we need to tell Android Studio that we need the files containing it, so it can recognise it later.

In order to do that, navigate to the Gradle Scripts in the left pane of your screen, there you'll see a file called build.gradle (Module: app). Open it and scroll to the bottom of the page. There you'll see this:

dependencies {
 compile fileTree(dir: 'libs', include: ['*.jar'])
}

Now what you need to do is just change that to this:

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])

compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.android.support:cardview-v7:25.0.1'
compile 'com.android.support:recyclerview-v7:25.0.1'
compile 'com.android.support:design:25.0.1'
}

That's it, you imported all the necessary files 👌🏻. Now let's go to your res/layout/ folder, once you're there go ahead and open activity_main.xml. As usual with layouts in android, we gotta write it's tags to create it, so we can give it height, width and anything your ❤️ might desire.

Now go ahead and write, or copy, this code into your layout. What it does basically is create the RecyclerView in our layout, make it as wide and as tall as the entire screen, and most importantly it gives it an unique id, RecyclerView.

<android.support.v7.widget.RecyclerView
android:id="@+id/RecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

You're basically done at this point with this layout file, but we gotta write a bit more XML before jumping to the Java part. Btw, if you run your app right now it's probably just generate some random things, don't care about that 👌🏻

Now, right click on your layout folder and tap on New > Layout Resource File. Just give it the name of item.xml and press enter. This layout file will be how every item of the list will look like. It's gonna have two text boxes two keep it simple. Basically the idea here is to make a template then change it's contents with what we want. Here's what you gotta do:

<android.support.v7.widget.CardView
android:id="@+id/item"
android:layout_width="match_parent"
android:layout_height="100dp">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

 <TextView 
  android:id="@+id/subtitle" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content"
  android:layout_below="@id/title" />

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

Congrats, we're all done with the XML part of the job. Now let's get to Java. Let's first review what we've done. We added the RecyclerView to our layout and created a template item. But by themselves they don't really know what to show. So let's add a logic to all of this.


Building the logic

 

As we're done with the XML, open your Java folder. We will write in Java the logic behind the ReyclerView. We'll need 3 main things to make this function properly. Firsly, we need a thing called the Adapter. This is like the backbone of the list, it controls what happens to every item. For example if you want to have the 3rd item of the list red, you'd do this kind of thing here. But you can also make changes to every single item at once.

I want you to right-click on the Java folder and go to New > Java Class, then just name it Adapter.java and press enter to create it. After we're finished, the whole structure will look like this:

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

 public static class ViewHolder extends RecyclerView.ViewHolder {
 ...
 ViewHolder(View itemView) {
super(itemView);
}
}

List<Item> list;

Adapter(List<Item> list) {
this.list = list;
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
return new ViewHolder(v);
}

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
 ...
}

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

This might look a bit scary at first, but at first you don't have to know everything that's happening there, most of it is autogenerated code. But what we need to focus on is the ViewHolder, here we'll declare all our views, in this case the two TextViews we just made in XML. After you've declared them, your code should look like this:

public static class ViewHolder extends RecyclerView.ViewHolder {

  //Initialise the Views
  TextView title;
TextView subtitle;

//Initialise the ViewHolder
ViewHolder(View itemView) {
super(itemView);
title= (TextView) itemView.findViewById(R.id.title);
subtitle = (TextView) itemView.findViewById(R.id.subtitle);
}
}

Now that we're done with that, we need to give the adapter a list to work with. It's like we're giving it a grocery list containing all our ingredients, after that we'll tell it what to do with them. In the below code, list is the list we'll tell our adapter to use, and <Item> is a custom class we'll soon define. To better wrap your head around it, just swap in your head <Item> with <Animal> and think we're going to add two attributes to it, Height and Color. In this case, list would contain for example Tiger, Dog, Cat, each having a Height and a Color. Height would be the title, and color would be the subtitle. This is the code for it:

//Adapter parameters
List<Item> list;

//Adapter initialization
Adapter(List<Item> list) {
this.list = list;
}

The next function is called onCreateViewHolder, you don't have to care about this one for now, just leave the code how it is.

The most important part of the Adapter is the onBindViewHolder. This function is what controls what happens to the individual items in the list. It sorts through the list and makes your desired changes to every item. To get a good idea of what you can do with it, let's make it change the text of our Title and Subtitle text fields and when we press on the Title it will show us a message with what it contains. You do it like this:

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
viewHolder.title.setText(list.get(position).getTitle());
  viewHolder.subtitle.setText(list.get(position).getSubtitle());
  
  viewHolder.title.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
  String text = list.get(position).getTitle());
Toast.makeText(view.getContext(), text, Toast.LENGTH_SHORT).show();
 });
}

At this point we're done with the Adapter, don't run your code just get cus you'll have some missing file errors. We're gonna create them right now. As you might've seen, when we set the text of the title and subtitle, we call a .getTitle(); function. We will now define this function is our <Item> file. Think of the function .getHeight(); for a given animal.

Create a new Java file called Item.java, and make it look like this:

public class Item {

  //Those are the values for a specific item in the list
String Title;
String Subtitle;

 //Here's where we initialise these values
public Photo(String Title, String Subtitle) {
this.Title= Title;
this.Subtitle = Subtitle;
}

  //This will be our function we talked about
public String getTitle() {
return Title;
}

//And of course, the second one
  public String getSubtitle() {
return Subtitle;
}
}

Now that we're done, your errors in your Adapter file will disappear. We're really close to finishing it all. Obviously, what we need to do now is define our RecyclerView in our MainActivity and then just enter some values in our list. Those values will be shown in the RecyclerView when we run the app.

First of all, open your MainActivity class, and before the onCreate function, declare these variables:

RecyclerView recyclerView;
Adapter adapter;
ArrayList<Item> list;

Then, in the onCreate(); function you need to initialise the variables, also define some options to the RecyclerView (you don't have to care about them, for now)

recyclerView = (RecyclerView) findViewById(R.id.RecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

list = new ArrayList<>();

Now, we need to add some content to our list, in order to do that just do this:

list.add(new Postare("Title1", "Subtitle1));
list.add(new Postare("Title2", "Subtitle2));
list.add(new Postare("Title3", "Subtitle3)); 
list.add(new Postare("Title4", "Subtitle4));

Finally, just link the RecyclerView to the Adapter, like this:

recyclerView.setAdapter(new Adapter(list));

You did it 

Wrapping it up, we're all done at this point, you can run your app and see what happens. From now you can change stuff around, add more content to the list, such as images or add more levels of interactivity. 

Let's make it a bit more fun by giving you a challange, try to find a way in which when you press one list item, the text gets underlined. Share your results with me on Instagram or Facebook