How to create a nested RecyclerView in Android
A nested RecyclerView is an implementation of a RecyclerView within a RecyclerView. An example of such a layout can be seen in a variety of apps such as the Play Store, where the outer (parent) RecyclerView is of vertical orientation, whereas the inner (child) RecyclerViews are of horizontal orientation. A similar layout is developed here.
Approach:
Step 1:Add the required dependencies
Add the following dependencies to the build. gradle file. The first dependency corresponds to RecyclerView and is mandatory. The second one is for CardView, which is optional depending on the UI requirements. Since CardView is used in the child RecyclerView layout here, the CardView dependency is added.
implementation ‘androidx.recyclerview:recyclerview:1.0.0’
implementation ‘androidx.cardview:cardview:1.0.0’
Note: For the correct versions of dependencies check here.
Step 2: Implement the parent RecyclerView
The parent RecyclerView is implemented in the activity_main file. Here, activity_main file only holds the parent RecyclerView, but it can be customized as per the requirements.
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/parent_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Step 3: Create item layout for the parent RecyclerView
Identify requirements for the parent layout and add Views corresponding to them in an XML layout file. Here, layout files are named as parent_item. In addition to the child RecyclerView, a TextView for the title is included.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/parent_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/child_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
</LinearLayout>
Step 4: Create item layout for the child RecyclerView
The layout of the items of the child RecyclerView is created in an XML layout file named child_item. Child RecyclerView includes an ImageView and a TextView, both wrapped inside a CardView.
The following image is used as the resource of the ImageView, thus it is added in the drawable resource folder.

icon
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="vertical"
android:padding="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/child_item_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/sample_image" />
<TextView
android:id="@+id/child_item_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Child Item" />
</LinearLayout>
</androidx.cardview.widget.CardView>
Step 5: Create Item classes for each of the RecyclerViews.
A Java class is required for each RecyclerView wherein the constructor initializes the parameters of the item and the getter and setter methods are declared. Thus, create the following Java classes:
- ChildItem: This class will implement the constructor, getter, and setter methods for the Views of the child_item layout that we wish to set dynamically.
- ParentItem: This class will implement the constructor, getter, and setter methods for the Views of the parent_item layout that we wish set dynamically.
public class ChildItem {
private int imageResId;
private String text;
public ChildItem(int imageResId, String text) {
this.imageResId = imageResId;
this.text = text;
}
public int getImageResId() {
return imageResId;
}
public void setImageResId(int imageResId) {
this.imageResId = imageResId;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
import java.util.List;
public class ParentItem {
private String title;
private List<ChildItem> childItemList;
public ParentItem(String title, List<ChildItem> childItemList) {
this.title = title;
this.childItemList = childItemList;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<ChildItem> getChildItemList() {
return childItemList;
}
public void setChildItemList(List<ChildItem> childItemList) {
this.childItemList = childItemList;
}
}
Step 6: Create an Adapter class for each of the RecyclerViews.
An adapter class is required to pass the data that is to be displayed in the views of RecyclerView. An adapter class is needed for the ChildItem as well as ParentItem classes.
- ChildAdapter: This is the adapter class for holding the information that is to be displayed in the views of the ChildItem class.
- ParentAdapter: This is the adapter class for holding the information that is to be displayed in the views of the ParentItem class.
In the ParentItemAdapter class, an instance of the class is created
RecyclerView.RecycledViewPool
This class is used to pass Views between the parent RecyclerView and the child RecyclerView.
package com.example.nestedrecyclerview;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class ChildAdapter extends RecyclerView.Adapter<ChildAdapter.ChildViewHolder> {
private List<ChildItem> childItemList;
public ChildAdapter(List<ChildItem> childItemList) {
this.childItemList = childItemList;
}
@NonNull
@Override
public ChildViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.child_item, parent, false);
return new ChildViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ChildViewHolder holder, int position) {
ChildItem childItem = childItemList.get(position);
holder.imageView.setImageResource(childItem.getImageResId());
holder.textView.setText(childItem.getText());
}
@Override
public int getItemCount() {
return childItemList.size();
}
public static class ChildViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public ChildViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.child_item_image);
textView = itemView.findViewById(R.id.child_item_text);
}
}
}
package com.example.nestedrecyclerview;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class ParentAdapter extends RecyclerView.Adapter<ParentAdapter.ParentViewHolder> {
private List<ParentItem> parentItemList;
private RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
public ParentAdapter(List<ParentItem> parentItemList) {
this.parentItemList = parentItemList;
}
@NonNull
@Override
public ParentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.parent_item, parent, false);
return new ParentViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ParentViewHolder holder, int position) {
ParentItem parentItem = parentItemList.get(position);
holder.textView.setText(parentItem.getTitle());
LinearLayoutManager layoutManager = new LinearLayoutManager(
holder.childRecyclerView.getContext(),
LinearLayoutManager.HORIZONTAL,
false
);
layoutManager.setInitialPrefetchItemCount(parentItem.getChildItemList().size());
ChildAdapter childItemAdapter = new ChildAdapter(parentItem.getChildItemList());
holder.childRecyclerView.setLayoutManager(layoutManager);
holder.childRecyclerView.setAdapter(childItemAdapter);
holder.childRecyclerView.setRecycledViewPool(viewPool);
}
@Override
public int getItemCount() {
return parentItemList.size();
}
public static class ParentViewHolder extends RecyclerView.ViewHolder {
TextView textView;
RecyclerView childRecyclerView;
public ParentViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.parent_item_title);
childRecyclerView = itemView.findViewById(R.id.child_recycler_view);
}
}
}
Step 7: Set the layout of parent RecyclerView and pass the arguments to both the RecyclerViews. The arguments to be passed to the RecyclerViews are given in the Java class that inflates the activity of the parent RecyclerView (here activity_main). So here the arguments will be passed in the MainActivity file.
Also, set the layout for the parent RecyclerView here itself.
package com.example.nestedrecyclerview;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView parentRecyclerView = findViewById(R.id.parent_recycler_view);
List<ChildItem> childItemList1 = new ArrayList<>();
childItemList1.add(new ChildItem(R.drawable.sample_image, "Child 1"));
childItemList1.add(new ChildItem(R.drawable.sample_image, "Child 2"));
List<ChildItem> childItemList2 = new ArrayList<>();
childItemList2.add(new ChildItem(R.drawable.sample_image, "Child 3"));
childItemList2.add(new ChildItem(R.drawable.sample_image, "Child 4"));
List<ParentItem> parentItemList = new ArrayList<>();
parentItemList.add(new ParentItem("Parent 1", childItemList1));
parentItemList.add(new ParentItem("Parent 2", childItemList2));
ParentAdapter parentAdapter = new ParentAdapter(parentItemList);
parentRecyclerView.setLayoutManager(new LinearLayoutManager(this));
parentRecyclerView.setAdapter(parentAdapter);
}
}
Output: