Open In App

How to Create RecyclerView with Multiple ViewType in Android?

Last Updated : 09 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

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.

multiple-viewtype


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.

activity_main.xml
<!-- 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:

icon_two

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
<!-- 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
<!-- 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:

ItemClass.java
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.

AdapterClass.java
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.
MainActivity.java
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);
    }
}

Output: Run on Emulator





Next Article
Article Tags :
Practice Tags :

Similar Reads