In Android, RecyclerView is an advanced and flexible version of ListView and GridView. It is a container used to display large amount of data sets that can be scrolled very efficiently by maintaining a limited number of views. RecyclerView was first introduced in Material Design in API level 21 (Android 5.0 i.e Lollipop).
Material Design brings lot of new features in Android that changed a lot the visual design patterns regarding the designing of modern Android applications. This new widget is a big step for displaying data because the GridView is one of the most commonly used UI widget. In RecyclerView android provides a lot of new features which are not present in existing ListView or GridView.
Basic RecyclerView XML code:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="abhiandroid.com.recyclerviewexample.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
Gradle Dependency to use RecyclerView:
The RecyclerView widget is a part of separate library valid for API 7 level or higher. Add the following dependency in your Gradle build file to use recyclerview.
Gradle Scripts > build.gradle and inside dependencies
dependencies { ... compile "com.android.support:recyclerview-v7:23.4.0" }
Table Of Contents
RecyclerView As Staggered Grid
In this article we will discuss how to use a RecyclerView for creating Staggered Grids. For that firstly we need to understand LayoutManager component of RecyclerView. Layout Manager is a very new concept introduced in RecyclerView for defining the type of Layout which RecyclerView should use. It contains the references for all the views that are filled by the data of the entry. We can create a Custom Layout Manager by extending RecyclerView.LayoutManager Class but RecyclerView Provides three types of in-built Layout Managers.
1. LinearLayoutManager: It is used for displaying Vertical or Horizontal List.
2. GridLayoutManager: It is used for displaying the items in the form of Grids.
3. StaggeredGridLayoutManager: It is used to show the items in staggered Grid.
In this article our main focus is on StaggeredGridLayoutManager because it is used to display the data in the form of staggered grids. By using this Layout Manager we can easily create staggered grid items.
In Android Pinterest and SamePinchh both apps are the best example of staggered grid. StaggeredGridLayoutManager is used for displaying the data items in staggered grid format and we can easily define the orientation for the items.
StaggeredGridLayoutManager is similar with GridLayoutManager but in this each grid have its own size(width and height). It automatically sets the items according to their height and width. The main difference between GridView and Staggered Grid is of varying size in staggered. Staggered Grid View shows asymmetric items in view.
Public constructor for StaggeredGridLayoutManager
• StaggeredGridLayoutManager(int spanCount, int orientation): It is used to create a StaggeredGridLayoutManager with given parameters. First parameter is used to set spanCount means number of columns if orientation is vertical or number of rows if orientation is horizontal, Second Parameter is used to set the Orientation, it should be vertical or horizontal.
Example: In below code snippet we show how to use this constructor in Android.
With Vertical Orientation:
// get the reference of RecyclerView RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); // set a StaggeredGridLayoutManager with 3 number of columns and vertical orientation StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(staggeredGridLayoutManager); // set LayoutManager to RecyclerView
With Horizontal Orientation:
// get the reference of RecyclerView RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); // set a StaggeredGridLayoutManager with 3 number of columns and horizontal orientation StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(staggeredGridLayoutManager); // set LayoutManager to RecyclerView
Example Of Vertical Staggered GridView using RecyclerView In Android Studio
Below is the example of RecyclerView As GridView in which we display staggered grids of Person Names with their images and setting default vertical orientation using RecyclerView.
In this example we are using StaggeredGridLayoutManager with vertical orientation and 3 span count value to display the items. Firstly we declare a RecyclerView in our XML file and then get the reference of it in our Activity. After that we creates two ArrayList for Person Names and Images. After that we set a StaggeredGridLayoutManager and finally we set the Adapter to show the grid items in RecyclerView. Whenever a user clicks on an item the full size image will be displayed on the next screen.
Step 1: Create a New Project and Name it RecyclerViewExample.
Step 2: Open Gradle Scripts > build.gradle and add RecyclerView Library dependency in it.
apply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion "24.0.1" defaultConfig { applicationId "abhiandroid.com.recyclerviewexample" minSdkVersion 16 targetSdkVersion 24 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:24.1.1' compile "com.android.support:recyclerview-v7:23.4.0" // dependency file for RecyclerView }
Step 3: Open res -> layout -> activity_main.xml (or) main.xml and add following code:
In this step we create a RecyclerView in our XML file.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="abhiandroid.com.recyclerviewexample.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
Step 4: Create a new drawable XML file in Drawable folder and name it custom_item_layout.xml and add the following code in it for creating a custom grid item.
In this step we create a drawable XML file in which we add the code for creating custom grid items.
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <!-- stroke with color and width for creating outer line --> <stroke android:width="1dp" android:color="#000" /> </shape>
Step 5: Create a new XML file rowlayout.xml for grid item of RecyclerView and paste the following code in it.
In this step we create a new xml file for item row in which we creates a TextView and ImageView to show the data in grid format.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/custom_item_layout" android:padding="5dp"> <!-- grid items for RecyclerView --> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:text="ABCD" android:textSize="20sp" android:textColor="#fff" /> </RelativeLayout>
Step 6 : Now open app -> java -> package -> MainActivity.java and add the below code.
In this step firstly we get the reference of RecyclerView. After that we creates two ArrayList’s for Person Names and Images. After that we set a StaggeredGridLayoutManager and finally we set the Adapter to show the grid items in RecyclerView.
package abhiandroid.com.recyclerviewexample; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import java.util.ArrayList; import java.util.Arrays; public class MainActivity extends AppCompatActivity { // ArrayList for person names ArrayList personNames = new ArrayList<>(Arrays.asList("Person 1", "Person 2", "Person 3", "Person 4", "Person 5", "Person 6", "Person 7", "Person 8", "Person 9", "Person 10", "Person 11", "Person 12", "Person 13", "Person 14")); ArrayList personImages = new ArrayList<>(Arrays.asList(R.drawable.person1, R.drawable.person2, R.drawable.person3, R.drawable.person4, R.drawable.person5, R.drawable.person6, R.drawable.person7, R.drawable.person1, R.drawable.person2, R.drawable.person3, R.drawable.person4, R.drawable.person5, R.drawable.person6, R.drawable.person7)); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // get the reference of RecyclerView RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); // set a StaggeredGridLayoutManager with 3 number of columns and vertical orientation StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(staggeredGridLayoutManager); // set LayoutManager to RecyclerView // call the constructor of CustomAdapter to send the reference and data to Adapter CustomAdapter customAdapter = new CustomAdapter(MainActivity.this, personNames, personImages); recyclerView.setAdapter(customAdapter); // set the Adapter to RecyclerView } }
Step 7: Create a new class CustomAdapter.java inside package and add the following code.
In this step we create a CustomAdapter class and extends RecyclerView.Adapter class with Viewholder in it. After that we implement the overrided methods and create a constructor for getting the data from Activity. In this custom Adapter two methods are more important first is onCreateViewHolder in which we inflate the layout item xml and pass it to View Holder and other is onBindViewHolder in which we set the data in the view’s with the help of ViewHolder. Finally we implement the setOnClickListener event on itemview and on click of item we display the selected image in full size in the next Activity.
package abhiandroid.com.recyclerviewexample; import android.content.Context; import android.content.Intent; 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 java.util.ArrayList; public class CustomAdapter extends RecyclerView.Adapter { ArrayList personNames; ArrayList personImages; Context context; public CustomAdapter(Context context, ArrayList personNames, ArrayList personImages) { this.context = context; this.personNames = personNames; this.personImages = personImages; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // infalte the item Layout View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false); // set the view's size, margins, paddings and layout parameters MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder return vh; } @Override public void onBindViewHolder(MyViewHolder holder, final int position) { // set the data in items holder.name.setText(personNames.get(position)); holder.image.setImageResource(personImages.get(position)); // implement setOnClickListener event on item view. holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // open another activity on item click Intent intent = new Intent(context, SecondActivity.class); intent.putExtra("image", personImages.get(position)); // put image data in Intent context.startActivity(intent); // start Intent } }); } @Override public int getItemCount() { return personNames.size(); } public class MyViewHolder extends RecyclerView.ViewHolder { // init the item view's TextView name; ImageView image; public MyViewHolder(View itemView) { super(itemView); // get the reference of item view's name = (TextView) itemView.findViewById(R.id.name); image = (ImageView) itemView.findViewById(R.id.image); } } }
Step 8: Create a new XML file activity_second.xml and add below code in it.
In this step we create a ImageView in our XML file to show the selected image in full size.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:background="#fff"> <ImageView android:id="@+id/selectedImage" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:scaleType="fitXY" /> </RelativeLayout>
Step 9: Create a new Activity and name it SecondActivity.class and add the below code in it.
In this step we get the reference of ImageView and then get Intent which was set from adapter of Previous Activity and then finally we set the image in ImageView.
package abhiandroid.com.recyclerviewexample; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ImageView; public class SecondActivity extends AppCompatActivity { ImageView selectedImage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); selectedImage = (ImageView) findViewById(R.id.selectedImage); // init a ImageView Intent intent = getIntent(); // get Intent which was set from adapter of Previous Activity selectedImage.setImageResource(intent.getIntExtra("image", 0)); // get image from Intent and set it in ImageView } }
Output:
Now run the App and you will see person name in staggered grid which can be scrolled in vertical direction created using RecyclerView.
Example Of Horizontal Staggered GridView using RecyclerView In Android Studio
Below is the second example of RecyclerView As Staggered GridView in which we display the grids of Person Names with their images with horizontal orientation by using RecyclerView.
In this example we are using StaggeredGridLayoutManger with horizontal orientation and 3 span count value which defines the number of rows. Firstly we declare a RecyclerView in our XML file and then get the reference of it in our Activity. After that we creates two ArrayList for Person Names and Images. After that we set a StaggeredGridLayoutManager and finally we set the Adapter to show the grid items in RecyclerView. Whenever a user clicks on an item the full size image will be displayed on the next screen.
Step 1: Create A New Project And Name It RecyclerViewExample.
Step 2: Open Gradle Scripts > build.gradle and add RecyclerView Library dependency in it.
apply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion "24.0.1" defaultConfig { applicationId "abhiandroid.com.recyclerviewexample" minSdkVersion 16 targetSdkVersion 24 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:24.1.1' compile "com.android.support:recyclerview-v7:23.4.0" // dependency file for RecyclerView }
Step 3: Open res -> layout -> activity_main.xml (or) main.xml and add following code:
In this step we create a RecyclerView in our XML file.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="abhiandroid.com.recyclerviewexample.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
Step 4: Create a new drawable XML file in Drawable folder and name it custom_item_layout.xml and add the following code in it for creating a custom grid item.
In this step we create a drawable XML file in which we add the code for creating custom grid items.
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <!-- stroke with color and width for creating outer line --> <stroke android:width="1dp" android:color="#000" /> </shape>
Step 5: Create a new XML file rowlayout.xml for grid item of RecyclerView and paste the following code in it.
In this step we create a new xml file for item row in which we creates a TextView and ImageView to show the data in grid format.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/custom_item_layout" android:padding="5dp"> <!-- grid items for RecyclerView --> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:text="ABCD" android:textSize="20sp" android:textColor="#fff" /> </RelativeLayout>
Step 6 : Now open app -> java -> package -> MainActivity.java and add the below code.
In this step firstly we get the reference of RecyclerView. After that we creates two ArrayList’s for Person Names and Images. After that we set a StaggeredGridLayoutManager with horizontal orientation and then finally we set the Adapter to show the grid items in RecyclerView.
package abhiandroid.com.recyclerviewexample; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import java.util.ArrayList; import java.util.Arrays; public class MainActivity extends AppCompatActivity { // ArrayList for person names ArrayList personNames = new ArrayList<>(Arrays.asList("Person 1", "Person 2", "Person 3", "Person 4", "Person 5", "Person 6", "Person 7", "Person 8", "Person 9", "Person 10", "Person 11", "Person 12", "Person 13", "Person 14")); ArrayList personImages = new ArrayList<>(Arrays.asList(R.drawable.person1, R.drawable.person2, R.drawable.person3, R.drawable.person4, R.drawable.person5, R.drawable.person6, R.drawable.person7, R.drawable.person1, R.drawable.person2, R.drawable.person3, R.drawable.person4, R.drawable.person5, R.drawable.person6, R.drawable.person7)); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // get the reference of RecyclerView RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); // set a StaggeredGridLayoutManager with 3 number of columns and horizontal orientation StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(staggeredGridLayoutManager); // set LayoutManager to RecyclerView // call the constructor of CustomAdapter to send the reference and data to Adapter CustomAdapter customAdapter = new CustomAdapter(MainActivity.this, personNames, personImages); recyclerView.setAdapter(customAdapter); // set the Adapter to RecyclerView } }
Step 7: Create a new class CustomAdapter.java inside package and add the following code.
In this step we create a CustomAdapter class and extends RecyclerView.Adapter class with ViewHolder in it. After that we implement the overrided methods and create a constructor for getting the data from Activity. In this custom Adapter two methods are more important first is onCreateViewHolder in which we inflate the layout item xml and pass it to View Holder and other is onBindViewHolder in which we set the data in the view’s with the help of ViewHolder. Finally we implement the setOnClickListener event on itemview and on click of item we display the selected image in full size in the next Activity.
package abhiandroid.com.recyclerviewexample; import android.content.Context; import android.content.Intent; 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 java.util.ArrayList; public class CustomAdapter extends RecyclerView.Adapter { ArrayList personNames; ArrayList personImages; Context context; public CustomAdapter(Context context, ArrayList personNames, ArrayList personImages) { this.context = context; this.personNames = personNames; this.personImages = personImages; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // infalte the item Layout View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false); // set the view's size, margins, paddings and layout parameters MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder return vh; } @Override public void onBindViewHolder(MyViewHolder holder, final int position) { // set the data in items holder.name.setText(personNames.get(position)); holder.image.setImageResource(personImages.get(position)); // implement setOnClickListener event on item view. holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // open another activity on item click Intent intent = new Intent(context, SecondActivity.class); intent.putExtra("image", personImages.get(position)); // put image data in Intent context.startActivity(intent); // start Intent } }); } @Override public int getItemCount() { return personNames.size(); } public class MyViewHolder extends RecyclerView.ViewHolder { // init the item view's TextView name; ImageView image; public MyViewHolder(View itemView) { super(itemView); // get the reference of item view's name = (TextView) itemView.findViewById(R.id.name); image = (ImageView) itemView.findViewById(R.id.image); } } }
Step 8: Create a new XML file activity_second.xml and add below code in it.
In this step we create a ImageView in our XML file to show the selected image in full size.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:background="#fff"> <ImageView android:id="@+id/selectedImage" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:scaleType="fitXY" /> </RelativeLayout>
Step 9: Create a new Activity and name it SecondActivity.class and add the below code in it.
In this step we get the reference of ImageView and then get Intent which was set from adapter of Previous Activity and then finally we set the image in ImageView.
package abhiandroid.com.recyclerviewexample; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ImageView; public class SecondActivity extends AppCompatActivity { ImageView selectedImage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); selectedImage = (ImageView) findViewById(R.id.selectedImage); // init a ImageView Intent intent = getIntent(); // get Intent which was set from adapter of Previous Activity selectedImage.setImageResource(intent.getIntExtra("image", 0)); // get image from Intent and set it in ImageView } }
Output:
Now run the App and you will see person name in staggered grid which can be scrolled in horizontal direction created using RecyclerView.
Error in below method does not override method from its super class method
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.name.setText((Integer) personNames.get(position));
holder.image.setImageResource((Integer) personImages.get(position));
// implement setOnClickListener event on item view.
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// open another activity on item click
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra(“image”, (Bundle) personImages.get(position)); // put image data in Intent
context.startActivity(intent); // start Intent
}
});
if anyone gets error on onBindViewHolder ‘method dosent override’, change
public class CustomAdapter extends RecyclerView.Adapter
to
public class CustomAdapter extends RecyclerView.Adapter
class CustomAdapter extends RecyclerView.Adapter
Hi, thank you for a good post, but I cannot understand, how can I change height of the first photos line at the second sample?
Thanks