Last Updated on March 2, 2019 by Aram
A RecyclerView is a great a way to show a large list of UI elements in an efficient way. You can combine TextViews, Buttons, ImageViews or any other UI elements and display them
To make a RecyclerView work and display properly, you have to define 2 main components:
RecyclerView Adapter
The adapter’s main role is to populate the RecyclerView with the data through the needed layout. The RecyclerView Adapter forces the use of the ViewHolder Design Pattern, which means that there will be 3 methods to override and a class to extend from RecyclerView.ViewHolder :
- onCreateViewHolder, which will be used to inflate the layout and create the holder)
- onBindViewHolder, which will be used to bind the data with the RecyclerView’s item through the ViewHolder )
- getItemCount, which is used to determine the number of items in the RecyclerView
The RecyclerView.ViewHolder class will provide the needed access to all the views within each row of the RecyclerView
Layout Manager
You have to provide a Layout Manager for the RecyclerView to be displayed on the screen.
The Layout Manager’s role is to organize the display of the item views and decide when to reuse views that are not being displayed (user has scrolled away from them).
You can use a LinearLayout Manager to have either a vertical or horizontal list of items, a GridLayout Manager to display your list in a grid view or a StaggeredGridLayout Manager, which will display the list in a grid view but the items won’t be organized evenly.
In this tutorial you will learn how to populate a RecycleView with in-memory collection. The same can apply for data from any source.
Note: This tutorial assumes you have a basic knowledge of RESTful APIs and how to consume them via Android through Retrofit library. Otherwise, you can check my tutorials about Retrofit in Android
Let’s get started
Open Android Studio and create a new Project, choose Empty Activity, then fill all the details with regards the app name, package name…etc. next hit finish and wait until Gradle finishes syncing and building the project.
Make sure the below exist in your app module’s build.gradle dependencies node
1 2 3 |
implementation 'com.android.support:appcompat-v7:27.1.1' implementation 'com.android.support:recyclerview-v7:27.1.1' implementation 'com.android.support.constraint:constraint-layout:1.1.3' |
The first thing to start with when building a RecyclerView, is to prepare the layout that will represent each item in the RecyclerView.
Right click on layouts folder, and choose new then layout resource file and name it person_item and change the root element to LinearLayout (You can use whatever Layout element you prefer).
Below is the code for the person_item.xml layout. Important Note: the parent layout height should always remain wrap_content
, if you set it as match_parent
, then at runtime, only the first item of the data collection within the RecyclerView will appear because it will fill the whole screen and no other items will be visible.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp"> <ImageView android:id="@+id/avatar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="10dp" android:orientation="horizontal"> <TextView android:id="@+id/name_label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Name:" android:textStyle="bold" /> <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="10dp" android:text="-" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="10dp" android:layout_marginTop="7dp" android:orientation="horizontal"> <TextView android:id="@+id/age_label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Age:" android:textStyle="bold" /> <TextView android:id="@+id/age" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="10dp" android:text="-" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="10dp" android:layout_marginTop="7dp" android:orientation="horizontal"> <TextView android:id="@+id/position_label" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Position:" android:textStyle="bold" /> <TextView android:id="@+id/position" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="10dp" android:text="-" /> </LinearLayout> </LinearLayout> </LinearLayout> |
Now that we have created our layout (View), let’s go ahead and create our model , which will hold the data that will be bound to our layout through the adapter.
Create a new package and name it models. Keeping your project structured within packages is quite important, it will help keep it well-organized and easy for future modifications.
Then inside the models package, create a new class and name it Person. It should look like the below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package com.codingsonata.recyclerviewapp.models; public class Person { private String name; private int age; private String position; public Person(String name, int age, String position) { this.name = name; this.age = age; this.position = position; } public String getName() { return name; } public int getAge() { return age; } public String getPosition() { return position; } } |
After we have prepared both of the model and the view, now we are ready to build our adapter. This adapter will be used to connect the collection of persons with the person_item layout through the ViewHolder Design Pattern.
Let’s also create a package that will hold the adapters and inside it let’s create a class with name PersonsAdapter. Usually, in a real app, you will have to prepare multiple adapter, each would be used to serve a specific RecyclerView. Moreover, It is also great to group all your adapters inside a dedicated package.
Below is the code that you will need for the Adapter.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
package com.codingsonata.recyclerviewapp.adapters; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.codingsonata.recyclerviewapp.R; import com.codingsonata.recyclerviewapp.models.Person; import java.util.List; public class PersonsAdapter extends RecyclerView.Adapter { private List persons; public PersonsAdapter(List persons) { this.persons = persons; } @NonNull @Override public PersonsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.person_item, parent, false); return new PersonsViewHolder(view); } @Override public void onBindViewHolder(@NonNull PersonsViewHolder holder, int position) { Person person = persons.get(position); holder.name.setText(person.getName()); holder.age.setText(String.valueOf(person.getAge())); holder.position.setText(person.getPosition()); } @Override public int getItemCount() { return persons.size(); } public class PersonsViewHolder extends RecyclerView.ViewHolder { private final TextView name; private final TextView age; private final TextView position; public PersonsViewHolder(View itemView) { super(itemView); name = itemView.findViewById(R.id.name); age = itemView.findViewById(R.id.age); position = itemView.findViewById(R.id.position); } } } |
For the purpose of this tutorial and to stay focused on the RecyclerView topic I prepared a small class with name PersonsFactory, which would create an in-memory collection of persons so that we can use it within our RecyclerView. Usually, in the real scenarios you will be getting your data collection from API sources.
Note: If you would like to learn about retrieving data from API in Android, you can check my tutorial series
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
package com.codingsonata.recyclerviewapp; import com.codingsonata.recyclerviewapp.models.Person; import java.util.ArrayList; import java.util.List; public class PersonsFactory { public static List createInMemoryData(){ List people = new ArrayList<>(); people.add(new Person("John", 39, "IT Director")); people.add(new Person("Lena", 24, "Credit Review")); people.add(new Person("Smith", 21, "Operations Trainee")); people.add(new Person("Adam", 31, "Technical Lead")); people.add(new Person("Kate", 26, "Senior Human Resources")); people.add(new Person("Robert", 33, "IT Manager")); people.add(new Person("Lora", 29, "Digital Marketing Lead")); return people; } } |
Now let’s add the RecyclerView UI Element inside the activity_main.xml layout file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" android:id="@+id/persons_recycler_view"> </android.support.v7.widget.RecyclerView> </android.support.constraint.ConstraintLayout> |
Now let’s go to our MainActivity and match the puzzle pieces all together.
We want to display a list of persons on the screen upon the creation of MainActivity, see the code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package com.codingsonata.recyclerviewapp; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import com.codingsonata.recyclerviewapp.adapters.PersonsAdapter; import com.codingsonata.recyclerviewapp.models.Person; import java.util.List; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView personsRecyclerView = findViewById(R.id.persons_recycler_view); List<Person> inMemoryData = PersonsFactory.createInMemoryData(); PersonsAdapter personsAdapter = new PersonsAdapter(inMemoryData); personsRecyclerView.setAdapter(personsAdapter); personsRecyclerView.setLayoutManager(new LinearLayoutManager(this)); personsRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); } } |
The last statement adds a horizontal line seperater between each item in the recycler view.
Now your RecyclerView is ready to be displayed. Press the Run button from your Android Studio and get impressed with your amazing scrollable RecyclerView.
See the screen below:
Well done! With this tutorial you have learned about a very important UI component which is the RecyclerView in Android.
If you liked my article please share it with your network, and if you are having trouble understanding or even problems with code with regards setting up your RecyclerView, please feel free to share your comments with me.
You can also check this guide from android developer site, it also explains pretty well the RecyclerView with example. Check it out.
Bonus
For my wonderful readers, allow me to share with you this beautiful masterpiece by J.S.Bach, English Suite No 1 BWV 806 A Major played by András Schiff