How to Create RecyclerView with Multiple ViewType in Android?
RecyclerView forms a crucial part of the UI in Android app development. It is especially important to optimize memory consumption when displaying a long list of items. A RecyclerView inflates a customized list of items, which can have either similar layouts or multiple distinct layouts. Here, we develop a RecyclerView with multiple ViewTypes. Following is an example of an Android RecyclerView with multiple views.

Approach
Step 1: Add the required dependencies
Create a new project in Android Studio and add the following dependencies in the build.gradle(:app) here under the Gradle Scripts section:TextView
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.cardview:cardview:1.0.0"
For more up-to-date versions of the dependencies, click . While the first dependency is mandatory, the second one is optional depending upon the UI requirements. Click on Sync Now and proceed.
Step 2: Implement RecyclerView in activity_main.xml
Create a layout that holds the main RecyclerView. Here, it has been created in the activity_main.xml file. The given layout contains merely a Welcome TextView and a RecyclerView, however, it can be customized as per the requirements. Code for activity_main.xml is given below.
<!-- Example layout for activity_main.xml -->
<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">
<TextView
android:id="@+id/welcome_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome"
android:textSize="24sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp" />
</LinearLayout>
Step 3: Add the required drawable file
Before proceeding further, make sure all the necessary drawable resources are added under the drawable resource directory. In this tutorial, only the following icon has been used:

Step 4: Create all the item layouts
Identify all the different layouts the RecyclerView is required to hold and implement them all in separate XML files under the layout resource directory. Here, two distinct layouts have been created. The first one is implemented in layout_one.xml while the second one in layout_two.xml. The first layout consists of just a wrapped inside a CardView. The following is its implementation.
<!-- layout_one.xml -->
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<TextView
android:id="@+id/text_view_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Item"
android:textSize="18sp"
android:padding="16dp" />
</androidx.cardview.widget.CardView>
The second item holds three elements wrapped inside a CardView.
- An ImageView
- A TextView
- Another TextView with a relatively smaller font size
<!-- layout_two.xml -->
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher_foreground" />
<TextView
android:id="@+id/text_view_two"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="18sp"
android:paddingTop="8dp" />
<TextView
android:id="@+id/text_view_three"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Subtitle"
android:textSize="14sp"
android:paddingTop="4dp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
Step 5: Create an Item class
Create a Java class that holds the public constructors corresponding to each layout. Thus, two constructors have been created here in the ItemClass.java file. In addition to constructors, the getter and setter methods too are declared here. This is done in order to safely access the private variables of the ItemClass outside of it.
This is how the ItemClass.java looks for the layouts created above:
package com.example.android.multilayoutrecyclerview;
// ItemClass
// ItemClass.java
public class ItemClass {
private int viewType;
private String text;
private int imageResource;
// Constructor for first layout
public ItemClass(int viewType, String text) {
this.viewType = viewType;
this.text = text;
}
// Constructor for second layout
public ItemClass(int viewType, int imageResource, String text) {
this.viewType = viewType;
this.imageResource = imageResource;
this.text = text;
}
public int getViewType() {
return viewType;
}
public String getText() {
return text;
}
public int getImageResource() {
return imageResource;
}
public void setText(String text) {
this.text = text;
}
public void setImageResource(int imageResource) {
this.imageResource = imageResource;
}
}
Step 6: Create the Adapter class
Create an adapter class to display the contents of the RecyclerView. In the Adapter class for multiple ViewType RecyclerViews, the following method is overridden in addition to the conventional onCreateViewHolder()
, onBindViewHolder()
and getItemCount()
methods.
getItemViewType()
method is solely responsible for choosing the layout corresponding to each item. Apart from adding an extra method, the other changes include defining a specific ViewHolder class for each of the item layouts. Follow the code given for a deeper understanding.
package com.example.android.multilayoutrecyclerview;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class AdapterClass extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ItemClass> itemClassList;
// public constructor for this class
public AdapterClass(List<ItemClass> itemClassList) {
this.itemClassList = itemClassList;
}
// Override the getItemViewType method
@Override
public int getItemViewType(int position) {
return itemClassList.get(position).getViewType();
}
// Create classes for each layout ViewHolder
static class LayoutOneViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private LinearLayout linearLayout;
public LayoutOneViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text);
linearLayout = itemView.findViewById(R.id.linearlayout);
}
private void setView(String text) {
textView.setText(text);
}
}
static class LayoutTwoViewHolder extends RecyclerView.ViewHolder {
private ImageView icon;
private TextView textOne, textTwo;
private LinearLayout linearLayout;
public LayoutTwoViewHolder(@NonNull View itemView) {
super(itemView);
icon = itemView.findViewById(R.id.image);
textOne = itemView.findViewById(R.id.text_one);
textTwo = itemView.findViewById(R.id.text_two);
linearLayout = itemView.findViewById(R.id.linearlayout);
}
private void setViews(int image, String textOne, String textTwo) {
icon.setImageResource(image);
this.textOne.setText(textOne);
this.textTwo.setText(textTwo);
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == ItemClass.LayoutOne) {
View layoutOne = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_one, parent, false);
return new LayoutOneViewHolder(layoutOne);
} else if (viewType == ItemClass.LayoutTwo) {
View layoutTwo = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_two, parent, false);
return new LayoutTwoViewHolder(layoutTwo);
}
return null;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof LayoutOneViewHolder) {
String text = itemClassList.get(position).getText();
((LayoutOneViewHolder) holder).setView(text);
((LayoutOneViewHolder) holder).linearLayout.setOnClickListener(view ->
Toast.makeText(view.getContext(), "Hello from Layout One!", Toast.LENGTH_SHORT).show());
} else if (holder instanceof LayoutTwoViewHolder) {
int image = itemClassList.get(position).getImageResource();
String textOne = itemClassList.get(position).getText();
String textTwo = itemClassList.get(position).getSubtitle();
((LayoutTwoViewHolder) holder).setViews(image, textOne, textTwo);
((LayoutTwoViewHolder) holder).linearLayout.setOnClickListener(view ->
Toast.makeText(view.getContext(), "Hello from Layout Two!", Toast.LENGTH_SHORT).show());
}
}
@Override
public int getItemCount() {
return itemClassList.size();
}
}
Step 7: Complete the MainActivity.java file
Following are the important tasks to be implemented in the MainActivity.java file.
- Set the content view as the XML activity wherein the main RecyclerView has been implemented, here activity_main.xml.
- Set the layout for the RecyclerView.
- Pass arguments to the RecyclerView.
- Set the Adapter.
package com.example.android.multilayoutrecyclerview;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
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);
// From the MainActivity, find the RecyclerView
RecyclerView recyclerView = findViewById(R.id.recyclerView);
// Create and set the layout manager for the RecyclerView
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
List<ItemClass> itemClasses = new ArrayList<>();
// Pass the arguments
itemClasses.add(new ItemClass(ItemClass.LayoutOne, "Item Type 1"));
itemClasses.add(new ItemClass(ItemClass.LayoutOne, "Item Type 1"));
itemClasses.add(new ItemClass(ItemClass.LayoutTwo, R.drawable.icon, "Item Type 2", "Subtitle"));
itemClasses.add(new ItemClass(ItemClass.LayoutOne, "Item Type 1"));
itemClasses.add(new ItemClass(ItemClass.LayoutTwo, R.drawable.icon, "Item Type 2", "Subtitle"));
itemClasses.add(new ItemClass(ItemClass.LayoutTwo, R.drawable.icon, "Item Type 2", "Subtitle"));
itemClasses.add(new ItemClass(ItemClass.LayoutOne, "Item Type 1"));
itemClasses.add(new ItemClass(ItemClass.LayoutTwo, R.drawable.icon, "Item Type 2", "Subtitle"));
// Set the adapter
AdapterClass adapter = new AdapterClass(itemClasses);
recyclerView.setAdapter(adapter);
}
}