How to use RecyclerView?

In my time of doing android devel­op­ment (which hasn’t been very long TBH) I noticed some­thing quite inter­est­ing. When someone that wants to know how to use a fea­ture of Android, like Recycler­View, you go to the google docs (like the recycler­View for Android) and they do a very good job at explain­ing how to imple­ment it. Thing I noticed is that some­times it can be very vague. So I am going to show you how I imple­ment the Recycler­View for myself.

NOTE: This may still not be 100% cor­rect but I find this works, and works well. If you have sug­ges­tions or ques­tions please leave it in the com­ments and I will help out as best I can. There will be a link to the Repo on Bit­Buck­et and the clone URL if you want to close the pro­ject your­self.

First we need to cre­ate a view in our lay­out that has the recycler­view view in.

It looks like a lot but there is a lot of boil­er­plate code here that will be used later on.

You will see from line 44 to 49 is where the Recycler­View has been added.

Once we have done that we need to ini­tial­ise the Recycler­View in the class and you can do this by adding it to your onCre­ate meth­od in Android Life­Cycle meth­ods, but what I like to do is cre­ate a sep­ar­ate meth­od and have all my Recycler­View ini­tial­isa­tion done in there. I will show you an example of my final ini­tial­isa­tion code later.

Then we need to add a lay­out man­ager to the recycler­view

Once we have done this we need to cre­ate an adapter for the Recycler­View. Cre­ate a new Class in your applic­a­tion and call it some­thing like NamesAd­apter or some­thing that is rel­ev­ant to the recycler­view con­tent.

One you have cre­ated the class you need to cre­ate a View that will rep­res­ent each row in the list of names. You will need 2 Views in this Lay­out. 1 being a Tex­tView to dis­play the name and anoth­er being an ImageView that will have an icon that will allow you to delete the name indi­vidu­ally.

My Lay­out looks like this in code:

and it will look like this:

Each row will look like this:

If you need to get this little bin icon you can go to https://material.io/icons/ and search for “delete” you will see the icon above and you can down­load it and add it to your pro­ject. If you want the dark ver­sion, just click on the black col­our before click­ing save PNG.

At the link above also look for “per­son add” and this will allow you to down­load the icon that is used in the Float­ingAc­tion­But­ton. Down­load the light ver­sion for this icon

Once this lay­out has been cre­ated we need to cre­ate a Vie­wHold­er in the Adapter we made. It will be an inner class. Mine looks like this:

All this does is allows us to have access to each view in the lay­out to allow us to modi­fy the data etc.

You will notice in the NamesAd­aper­Vie­wHold­er meth­od in the Vie­wHold­er Class the id’s used in the find­View­By­Id are the same in the View we cre­ated earli­er that will rep­res­ent each row.

So cur­rently our whole class looks like this:

Now we need to start adding code to the par­ent class. First our NamesAd­apter needs to extend RecyclerView.Adapter<{Our cus­tom Vie­wHold­er we cre­ated earli­er}>

This is what my 1st line looks like

Once we have done this, we will be get­ting an error ask­ing us to imple­ment meth­ods. To do this just click on the line that is errored, then click Code in the menu bar and then click Imple­ment Meth­ods then select all and click OK.

You will be left with a class like this one:

Once you have done this, you will need to make a few changes to the meth­ods, but first, lets cre­ate a loc­al copy of the List of names we going to need in the adapter.

Add the fol­low­ing line to the class NamesAd­apter like this:

Next you need to get use the row lay­out you made. So in the meth­od onCre­ateVie­wHold­er we need to change it to the fol­low­ing:

Once that is com­plete we need to start mak­ing changes to the onBind­Vie­wHold­er.

What this meth­od does, is in simple form, it iter­ates through the list of names and pop­u­lates the views with the data in the List.

So we need to do the fol­low­ing:

This line gets the cur­rent object at the pos­i­tion and allows us to use the data in that object.

The only data we have in a list of Strings is just a simple String.

The next line is where we get the String from pos­i­tion x and set it to our Tex­tView we cre­ated in the name_row.xml lay­out.

To do this you type:

hold­er gives us access to all the Views in our cus­tom Vie­wHold­er and allows us to add data to the views.

Now that it gets each of the names from the list and sets it to the Tex­tView we need to allow our delete but­ton to do some­thing when we tap on it. To do this we type the fol­low­ing:

We will use this sec­tion of code later on once we have cre­ated some meth­ods needed.

Next we need to modi­fy the getItem­Count() meth­od. All you need to do is change the line from

to the fol­low­ing:

Now that this is all com­plete we need to cre­ate a few meth­ods in the NamesAd­apter class that allow us to add, remove and retrieve data from the adapter.

Cre­ate a meth­od under the getItem­Count meth­od and call it get­Names() like below:

This meth­od will allow us to get the cur­rent list of names in the adapter. This is used to save the mod­i­fied list of names when the device rotates because, in Android, when the device rotates, the activ­ity is killed then recre­ated and we need to save data before its killed in order to repop­u­late the views.

Next, under the get­Names meth­od, cre­ate a meth­od called addNames(List<String> aNames). Like below:

This is where things get inter­est­ing. In this meth­od you will notice a meth­od called noti­fy­Item­RangeIn­ser­ted(). What this meth­od does, is it asks for the cur­rent size of your list before the data is inser­ted and the size of data that you are adding into the list. This is done so the adapter knows where to add the items as well as how many items its adding to the list.

The line before the noti­fy­Item­RangeIn­ser­ted meth­od is where we add the list of names to the loc­al list object in the adapter. We do a null check just incase the list that is passed in is null for some reas­on.

Now that we can add a list of names to the adapter, we need to be able to remove a name from the adapter. To do this cre­ate anoth­er meth­od in the adapter called removeName(int aPos­i­tion). It should look like below:

Again you will notice a meth­od here that is called notifyItemRemoved(aPosition). What this does is sim­il­ar to noti­fy­Item­RangeIn­ser­ted() except it noti­fies the adapter that an item has been removed at pos­i­tion x. Anoth­er thing this noti­fy­Item­Re­moved() meth­od does is auto­mat­ic­ally starts and stops the anim­a­tions for when an item has been removed from the list. What we do before the noti­fy­Item­Re­moved() meth­od is remove the item from the loc­al list of Strings by call­ing names.remove(aPosition). This removes the item at that pos­i­tion in the list.

One more meth­od to cre­ate in the adapter. Cre­ate a meth­od called addName(String aName). What this meth­od will do is add a single name to the list. Type the fol­low­ing:

Again you will see a noti­fy­ItemIn­ster­ted() meth­od and I pass in the full size of the list of names. This will add the name to the end of the list.

Now we can return back to the onBind­Vie­wHold­er and add the fol­low­ing line to our onClick meth­od:

You always need to use the holder.getAdapterPosition() meth­od as using the meth­od vari­able “pos­i­tion” is not reli­able espe­cially when adding and remov­ing items from the list.

So if you have fol­lowed this all cor­rectly your class should look some­thing like this:

Now we can return to our activ­ity and make some changes there.

In the onCre­ate meth­od lets cre­ate a list of names that will be used when ever the app starts up.

First cre­ate a Class vari­able called mNames and is a List<String>. So type at the top of your class:

Once you have com­pleted this, we need to cre­ate a Class vari­able for our adapter class. Do this below the line we just typed in:

Now that we have done this lets use our adapter. On the line where you set the lay­out man­ager on our Recycler­View below that type:

this cre­ates a new object of our Adapter and sets the adapter to the Recycler­View by using the setAd­apter() meth­od. As I said earli­er on I like to add the recycler­View con­fig­ur­a­tion to a sep­ar­ate meth­od as this looks neat­er. So my onCre­ate looks some­thing like this:

If you run the applic­a­tion it “works” and the reas­on I put works in inver­ted com­mas is because your list will be empty. Reas­on is because we didn’t call the addNames() meth­od in our adapter, but first we need data to add to the adapter. Lets cre­ate a list of names that will be added to the adapter on first run of the app.

We only want this list added on first run so what I do is, in my onCre­ate meth­od I type the fol­low­ing:

saved­In­stanceState will ALWAYS be null on first run of the applic­a­tion, later on we will use it when its not null to retrieve the mod­i­fied list of names from the adapter.

After we have added a list of names to the mNames ArrayL­ist we need to add this list to our adapter.

Do this by call­ing, after you cre­ated and added data to the list. So below the if state­ment, but not in the if state­ment.

So your activ­ity should look some­thing like this:

If you run the app now, the applic­a­tion will work fine. You can eas­ily remove one name at a time by click­ing the delete icon.

You will notice how ever that every time you rotate the device, the list is empty and you will have to kill the applic­a­tion then reopen the applic­a­tion. Lets fix this issue now.

First lets add a meth­od to our activ­ity class that will allow us to retrieve the mod­i­fied list of names from our adapter and restore it once the activ­ity is recre­ated.

Type the fol­low­ing:

What this does is uses the meth­od we cre­ated in the adapter called get­Names() which stores the list of names in the class vari­able in our Home­Activ­ity class. I always do a null check on the adapter just to make sure the adapter will nev­er be null.

The onPause meth­od is always called just before the activ­ity is called allow­ing us to save data that we want to retrieve after the rota­tion has com­pleted. If you do net­work calls, this will pre­vent calls being done every time the device is rotated and in doing so, saves data usage on the device.

Then we need to save this data in order to retrieve it once the activ­ity has been recre­ated. To do this you need to over­ride the meth­od onSa­veIn­stanceState.

Now whats hap­pen­ing at this point is when we turn the phone, before the activ­ity is des­troyed, it saves the list of names into a Bundle called out­State. The activ­ity is then des­troyed. Now we need to get the data from the Saved­In­stanceState object when the activ­ity is recre­ated. To do this, in your onCre­ate where we have an if state­ment that checks if saved­In­stanceState == null, the else should con­tain the fol­low­ing line:

key” is used so that if we are sav­ing oth­er data before the rota­tion, we know which object is which when retriev­ing it.

so the if state­ment should look like this when you done:

Now when you run the applic­a­tion, and rotate the device, the applic­a­tion should save the data and re-add it to the adapter when it’s cre­ated.

Now lets start adding the fea­ture that allows the user to add their own names to the list. To do this we need to start using the oth­er views that are found in my activity_home.xml

Below where we typed:

At the top of the class add the fol­low­ing 2 lines of code:

and in the onCre­ate meth­od of our class add the fol­low­ing:

This all allows us to access the Tex­tIn­putEdit­Text and Tex­tIn­put­Lay­out views in our xml of the Home­Activ­ity class.

Lets now con­fig­ure the float­ing action but­ton:

Type in the onCre­ate after you have ini­tial­ise the mNamesEdit­Text and mNamesLay­out Views:

now lets add an onClick­Listen­er to the Float­ingAc­tion­But­ton that will do some­thing when a user taps on the but­ton. Add this after you have ini­tial­ised the Float­ingAc­tion­But­ton

Now we have some­where to add code that will allow us to get the data from the Tex­tIn­putEdit­Text that a user types in and adds it to our adapter.

First cre­ate an if state­ment like this in the onClick() meth­od of our Float­ingAc­tion­But­ton:

What this state­ment does is, Checks if the Tex­tIn­putEdit­Text is not empty, if it isn’t empty, dis­able any errors on the Tex­tIn­put­Lay­out, add the text that is  typed into the Tex­tIn­putEdit­Text to the adapter and then clear the text in the Tex­tIn­putEdit­Text. If the Tex­tIn­putEdit­Text is empty, dis­play an error on the Tex­tIn­put­Lay­out telling the user to enter a name into the Tex­tIn­putEdit­Text.

If you run and try the app out you will notice that it works fine. You are able to add and remove names that you wish, rotate the device and the same list is still avail­able for you to modi­fy as you wish.

One annoy­ance you will notice is the key­board, it keeps pop­ping up at the wrong times, like when you want to just view the list. This can be resolved by adding the last meth­od to the Activ­ity class called hideKey­board().

All this meth­od does is allows us to hide the key­board when we dont need it. You add this meth­od to the onCre­ate after setSupportActionBar(toolbar) as well as in the onClick of our Float­ingAc­tion­But­ton after we have cleared the text, if the text in the Tex­tIn­putEdit­Text is not empty.

So at the end of it all your Activ­ity should look some­thing like this:

You can clone this pro­ject by using the fol­low­ing com­mand:

git clone https://Stillie@bitbucket.org/Stillie/recyclerviewtutorial.git

or you can view the pro­ject at https://bitbucket.org/Stillie/recyclerviewtutorial/

Please leave any com­ments, sug­ges­tions or ques­tions you have below and I will do my best at help­ing out.


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.