Introduction
Learn to implement android recyclerview in simple step by step demo. In this android recyclerview tutorial, we’ll implement a horizontal list with recyclerview. In the previous tutorial, we have already created a vertical list using recycler view.
Just in case you have not gone through the previous tutorial, I’ll repeat the basic information about it. Android ListView is a widget that displays a list of scroll-able items. While implementing listview, we use an adapter that inserts the items in the list from a source like database query etc. I have not written any blog on listview, as it’s an older widget and we currently have advanced version of the listview and it’s called recyclerview. With recyclerview, Android addressed multiple limitations of listview and also made it more efficient. For example, recyclerview has built-in support for animation which was not the case in listview. Recyclerview forces using the ViewHolder pattern. With recyclerview, we can implement both vertical and horizontal scrolling. But in listview, only vertical scrolling is enabled.
Here, in this tutorial, we will cover max of these features introduced with recyclerview.
NOTE:- Your most reliable source of information for listview is here and recyclerview is here.
App Demo
Once we complete the implementation steps following this tutorial, we will see an app as below –
Tech Stack
Following are the tech stack used in this app development.
1 2 |
Android Studio 3.0.1 JAVA for Android programming |
Basic tasks for implementing recyclerview
Following are the 5 basic tasks while implementing recyclerview –
- Add recycler view to activity_main
- Create a layout xml depicting an item in the list
- Data model to feed recyclerview
- Custom adapter for the recyclerview
- Link customer adapter to recyclerview
Let’s get started
Create an empty project
- Launch Android Studio and click: File –> New –> New Project…
- A “Create New Project” dialog box will open; we’ll provide the app name and company domain. I have entered following details, you can provide the name/domain as per your choice and preference.
- Application Name:- ItcRecyclerViewHorizontalList
- Company Domain:- iteritory.com
- Click on Next button. In the next window, select the minimum SDK version; you can choose as per your preference. In this case, I have chosen API 16: Android 4.1 (Jelly Bean). Click Next button.
- In the next window, select “Empty Activity“. Click Next button.
- In the next window, let’s keep the Activity Name and Layout Name to default. Click Finish button.
- I’ll change the app name a bit here, traverse and open res–> values –> strings.xml. Find the line with app_name attribute. Change the value to “My RecyclerView App”.
List we’ll implement using RecyclerView
I have used few images in this tutorial (source: google search) for demonstration purpose and same can be found (along with the codebase) in the github repository.
Add recyclerview dependency
In the app level build.gradle file, we’ll add the dependency for recyclerview –> implementation ‘com.android.support:recyclerview-v7:26.1.0’. Once added, the build.gradle file will look like –
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 |
apply plugin: 'com.android.application' android { compileSdkVersion 26 defaultConfig { applicationId "com.iteritory.itcrecyclerviewhorizontallist" minSdkVersion 16 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' implementation 'com.android.support:recyclerview-v7:26.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' } |
Add/Modify layout files
Add recyclerview widget to activity_main.xml
In case you have content_main.xml and it refers to activity_main, you can add recyclerview widget in content_main.xml. In my case, Android studio created only activity_main.xml. Hence, we will add the the recyclerview widget in activity_main.xml. Post modification, my activity_main file looks like below –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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="com.iteritory.itcrecyclerviewhorizontallist.MainActivity"> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <android.support.v7.widget.RecyclerView android:id="@+id/idRecyclerViewHorizontalList" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </RelativeLayout> |
Add layout file depicting an item in the horizontal list
Right click on res -> layout folder and then click on New –> Layout resource file menu item. A dialog box will open up; provide the File name as “horizontal_list_grocery_item” and click OK button. Add an imageview and textview in the layout file. This is the layout of how each item in list will look like. Post modification, my layout file looks like below –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/idProductImage" android:layout_width="50dp" android:layout_height="50dp"/> <TextView android:id="@+id/idProductName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30dp"/> </LinearLayout> |
Write Data Model Class
Next, we will write a model class (Grocery.java) depicting a grocery item in our list. We’ll use following fields –
- an image to display the picture of the grocery product
- Name of the product
Create a new package called model inside com.iteritory.itcrecyclerviewhorizontallist. Create the model class as below inside model package –
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.iteritory.itcrecyclerviewhorizontallist.model; /** * Created by Sadruddin on 12/10/2017. */ public class Grocery { public int productImage; public String productName; public Grocery(String productName, int productImage) { this.productImage = productImage; this.productName = productName; } public int getProductImage() { return productImage; } public void setProductImage(int productImage) { this.productImage = productImage; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } } |
Write custom adapter for the recyclerview
Next, we will create a custom adapter class that will inflate the layout file horizontal_list_grocery_item.xml (that we created above). Create a new package called adapter inside com.iteritory.itcrecyclerviewhorizontallist. Write the adapter class inside adapter package.
The customer adapter class extends RecyclerView.Adapter and overrides 3 methods –
- onCreateViewHolder() – inflates the grocery_item.xml layout
- onBindViewHolder() – the data (product image, product name) is retrieved from the object and is set to each item/row in the list. We’ll also override imageView onClick method to display a toast saying which item is selected.
- getItemCount() – returns the numbers of items/rows in the list.
We have also defined the view holder in the same adapter class. All combined, the adapter class looks like –
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 |
package com.iteritory.itcrecyclerviewhorizontallist.adapter; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.iteritory.itcrecyclerviewhorizontallist.R; import com.iteritory.itcrecyclerviewhorizontallist.model.Grocery; import java.util.List; /** * Created by Sadruddin on 12/24/2017. */ public class RecyclerViewHorizontalListAdapter extends RecyclerView.Adapter<RecyclerViewHorizontalListAdapter.GroceryViewHolder>{ private List<Grocery> horizontalGrocderyList; Context context; public RecyclerViewHorizontalListAdapter(List<Grocery> horizontalGrocderyList, Context context){ this.horizontalGrocderyList= horizontalGrocderyList; this.context = context; } @Override public GroceryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //inflate the layout file View groceryProductView = LayoutInflater.from(parent.getContext()).inflate(R.layout.horizontal_list_grocery_item, parent, false); GroceryViewHolder gvh = new GroceryViewHolder(groceryProductView); return gvh; } @Override public void onBindViewHolder(GroceryViewHolder holder, final int position) { holder.imageView.setImageResource(horizontalGrocderyList.get(position).getProductImage()); holder.txtview.setText(horizontalGrocderyList.get(position).getProductName()); holder.imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String productName = horizontalGrocderyList.get(position).getProductName().toString(); Toast.makeText(context, productName + " is selected", Toast.LENGTH_SHORT).show(); } }); } @Override public int getItemCount() { return horizontalGrocderyList.size(); } public class GroceryViewHolder extends RecyclerView.ViewHolder { ImageView imageView; TextView txtview; public GroceryViewHolder(View view) { super(view); imageView=view.findViewById(R.id.idProductImage); txtview=view.findViewById(R.id.idProductName); } } } |
Stitch all together in MainActivity
We have written so many components so far. Now it is the time to stitch it together to render a vertical list using recyclerview. Here in this class, we will –
- instantiate the custom adapter
- Set a layout manager for the recycler view
- Link recycler view with the custom adater
- Feed data and refresh the adapter
- Well!! that’s it, we’ll have our recycler view working fine and awesome.
Let’s take a look how our MainActivity.java looks like post all modification –
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 |
package com.iteritory.itcrecyclerviewhorizontallist; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import com.iteritory.itcrecyclerviewhorizontallist.adapter.RecyclerViewHorizontalListAdapter; import com.iteritory.itcrecyclerviewhorizontallist.model.Grocery; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private List<Grocery> groceryList = new ArrayList<>(); private RecyclerView groceryRecyclerView; private RecyclerViewHorizontalListAdapter groceryAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); groceryRecyclerView = findViewById(R.id.idRecyclerViewHorizontalList); // add a divider after each item for more clarity groceryRecyclerView.addItemDecoration(new DividerItemDecoration(MainActivity.this, LinearLayoutManager.HORIZONTAL)); groceryAdapter = new RecyclerViewHorizontalListAdapter(groceryList, getApplicationContext()); LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false); groceryRecyclerView.setLayoutManager(horizontalLayoutManager); groceryRecyclerView.setAdapter(groceryAdapter); populategroceryList(); } private void populategroceryList(){ Grocery potato = new Grocery("Potato", R.drawable.potato); Grocery onion = new Grocery("Onion", R.drawable.onion); Grocery cabbage = new Grocery("Cabbage", R.drawable.cabbage); Grocery cauliflower = new Grocery("Cauliflower", R.drawable.cauliflower); groceryList.add(potato); groceryList.add(onion); groceryList.add(cabbage); groceryList.add(cauliflower); groceryAdapter.notifyDataSetChanged(); } } |
Conclusion
So folks, in this tutorial, we learnt how to create a horizontal list using recyclerview. I have intentionally used an image along with a text, so that we learn how to inflate both such widgets in a single tutorial. And practicaly, if you see most of the times, we use image in the list.
Happy learning!