DEV Community

loading...
Cover image for Room database. RecyclerView Part 1

Room database. RecyclerView Part 1

Tristan Elliott
I am not a cat
・5 min read

Introduction

  • This series is going to be dedicated to the basics of Android Room library. I will be following the official google guide, HERE but I will be working in an order that makes more sense to me.

A quick word

  • This post and the next post are going to be part 1 and 2, describing how we set up a RecyclerView to use with Room database.

What is a RecyclerView

  • A RecyclerView makes it easy to efficiently display large sets of data. All we have to do is to supply the data and how each data item will look and the RecyclerView library dynamically creates the items when they are needed.
  • As the name implies, RecyclerView recycles those individual items, when an item scrolls off the screen, RecyclerView doesn't destroy its view. Instead RecyclerView reuses the view for new items that have scrolled on screen. This reuse greatly improves our apps responsiveness and reduces the power consumption.
  • Basically RecyclerView is a class that makes displaying data much easier.

Key parts of the RecyclerView

  • There are 4 main classes that the RecyclerView uses in order to build a dynamic list for us. This post will only be looking at the ViewHolder

1) ViewGroup : RecyclerView is a ViewGroup that will contain the views corresponding to our data. It's a view itself, so add RecyclerView into your layout the same way you would any other UI component, dynamically or through the XML.

2) ViewHolder : Each individual element in this list is defined by a ViewHolder object. When the ViewHolder is created, it doesn't have any data associated with it. After the ViewHolder is created the RecyclerView binds it to its data. You define the ViewHolder by extending RecyclerView.ViewHolder.

3) Adapter : The RecyclerView requests those views, and binds the views to their data, by calling methods in the adapter. We define the adapter by extending RecyclerView.Adapter.

4) Layout Manager : The layout manager arranges the individual elements in our dynamic list and performs a number of optimizations. We can use one of the layout managers to provided to us by the RecyclerView library.

  • So just a quick recap, we need 4 things in order to have a successful RecyclerView

1) ViewGroup : Add RecyclerView to the UI.
2) ViewHolder : Represents individual items.
3) Adapter : Requests and binds data.
4) Layout Manager : Defines layout of our RecyclerView.

  • The RecyclerView is actually much more complicated and I urge you to read more about it HERE

Creating the ViewHolder

  • To get started create a new class and call it WordViewHolder.
  • Remember that this class will be using to represent our individual items inside the RecyclerView list.
  • Also the xml files that I am using can be found HERE.
  • With that being said, lets look at some code.
public class WordViewHolder extends RecyclerView.ViewHolder{
    private final TextView wordItemView;

    public WordViewHolder( View itemView) {
        super(itemView);
        wordItemView = itemView.findViewById(R.id.textView);
    }

    public void bind(String text){
        wordItemView.setText(text);
    }

    static WordViewHolder create(ViewGroup parent){
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.recyclerview_item,parent,false);
        return new WordViewHolder(view);
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Now that we can see the code pasted above lets walk through it line by line.

public class WordViewHolder extends RecyclerView.ViewHolder{}

  • The first thing that we have to do is to extends RecyclerView.ViewHolder. This is mandatory and it is how the system will recognize that this class is going to be used for our ViewHolder object. As soon as you will do this you will notice an error that states:

There is no default constructor available on ViewHolder

  • So why are we getting this error? Well in order to answer this question you have to understand two things the Java compiler is doing automatically for us:

1)Automatic constructor : Since we have not defined a constructor yet the java compiler will create a default, no argument constructor for us.

2)Automatic super() : When using extends, if we do not define a super() call in the constructor(has to be the first line), the compiler will insert a default no argument super() for us.

  • So by just creating a class and using extends the Java compiler automatically creates this for us:
public WordViewHolder() {
        super();
    }
Enter fullscreen mode Exit fullscreen mode
  • super() is how we call the constructor in the super class so when we call super() we are calling the constructor of ViewHolder. Why does the compiler do this for us? Well it is done to reduce the amount of runtime errors and instead give us compile time errors which are much nicer and easier to deal with.

-To fix this error just hover of the red error indicator and click create constructor matching super. This will automatically create the constructor that we need.

  • The reason we are able to Access ViewHolder through RecyclerView.ViewHolder is because ViewHolder is a static class nested inside of the RecyclerView class. A static nested class acts exactly as a normal class, the only difference being that we have to access it through the surrounding class.

private final TextView wordItemView;

  • This is an instance variable meant to hold a reference to the TextView that we have created in a separate .XML file for our individual view. This variable will be used to hold information from our list which we will eventually use it to display on the screen.

public WordViewHolder( View itemView){}

  • This is our constructor for this class and it accepts one argument of type View. This view will actually be a inflated view of our individual item. In this constructor we call super(itemView);, as we discussed earlier, this will call the constructor of ViewHolder. wordItemView = itemView.findViewById(R.id.textView); will be used to find the TextView of our inflated view and assign it to the instance variable called wordItemView. Without this we can not bind any data to our TextView.

public void bind(String text){}

  • Despite this method being called bind, it is actually just a setter method for the wordItemView variable. As you can see it takes a argument of type String and then we use that string to set our instance variable, like this wordItemView.setText(text);. This method will be used by our Adapter, which we will see in the next post.

static WordViewHolder create(ViewGroup parent)

  • Notice that we have defined this as a static method. We do this so that we can use this method without having to instantiate our WordViewHolder class. Next notice that we pass it an argument of type ViewGroup, a ViewGroup is just a View that is used to store other Views. parent is actually our RecyclerView in this case.

  • Then we have the LayoutInflater which is used to turn .XML files into actual UI. So anytime you see LayoutInflater, know that UI is about to be created. .from(parent.getContext() uses the context from the parent argument to return the actual LayoutInflater. Now we can call .inflate(), this is the method that does the actual inflating and it takes 3 parameters:

1) Resource : The first parameter is an id for the layout XML file which will be inflated.

2) Root : This is the parent of our inflated view and we can actually leave it null since attachToRoot is false. However, since the tutorial I am using does not leave it null, I will also not leave it null.

3) AttachToRoot : A boolean value that indicates whether this inflated view should be attached to the root. For us the root is our parent variable. We set this value to false to indicate that we want the RecyclerView to attach it, not this method.

  • Lastly we call return new WordViewHolder(view); which returns a new instance of our WordViewHolder class. This entire method will be heavily utilized by our adapter class as you will see in the next post

Conclusion

  • Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on Twitter.

Discussion (0)