RecyclerView Multiple View Types in Android

RecyclerView Multiple View Types in Android

In order to display a list in your application, we all must have used RecyclerView in Android. For example, the emails in the Gmail app, the feeds on Facebook and Instagram, messages in WhatsApp, all are done with the help of RecyclerView.

But one thing that you might have noticed is that while using RecyclerView, we define a view and the list items are displayed according to that view only. But what if you want to add different view types in the RecyclerView, you can add Multiple Views in the same RecyclerView.

Welcome to MindOrks! In this blog, we are going to learn how to use Multiple Views in RecyclerView.

You can find the whole project used in this tutorial from here.

So, let's get started with the project setup.

RecyclerView Multiple View

We can add multiple views in a RecyclerView. For example, the feed page on Facebook is an example of Multiple View. You can add image, or video, or text or a combination of all in the same RecyclerView.

Another example can be WhatsApp chatting. The message that we send can be thought to be placed in a RecyclerView. So, when you send the message, it appears on the right-hand side of the screen. But if someone from the other side sends a message, then it appears on the left-hand side. So, there is a change in the view type.

In this blog, we will learn how to do this. We will create a RecyclerView and add two different views into it. You can create more view types according to your use-case.

Open AndroidStudio and create a project

  • Project Name: RecyclerViewMultiTypeExample
  • Language: Kotlin

Creating Views for the project

In our project, we are going to use two views i.e. item_view_1.xml and item_view_2.xml.

The code for the item_view_1.xml is:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#0091ea"
    android:paddingLeft="24dp"
    android:paddingRight="24dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:gravity="center_vertical"
        android:text="View 1 TextView"
        android:textColor="#FFFFFF"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@drawable/link_on"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

The code for the item_view_2.xml is:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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="wrap_content"
    android:background="#00bfa5"
    android:paddingLeft="24dp"
    android:paddingRight="24dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:gravity="center_vertical"
        android:textColor="#000000"
        android:text="View 2 TextView"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@drawable/link_off"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Data class

To store the data to be displayed on the views, we need a data class. Create a data class name Data and add the below code:

data class Data(val viewType: Int, val textData: String)

The viewType will tell which view we are using i.e. either item_view_1 or item_view_2 and textData will store the data that will be displayed on the TextView.

Adapter for RecyclerView

Now, for the RecyclerView, we need to create an Adapter class that will store all the logic of RecyclerView i.e. when to display which view.

Create an Adapter class named RecyclerViewAdapter.

In the RecyclerViewAdapter class, we will check if the desired view is item_view_1 then the content of item_view_1 will be displayed otherwise we will display the content of item_view_2.

The following is the code for the RecyclerViewAdapter class:

class RecyclerViewAdapter(context: Context, list: ArrayList<Data>) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        const val VIEW_TYPE_ONE = 1
        const val VIEW_TYPE_TWO = 2
    }

    private val context: Context = context
    var list: ArrayList<Data> = list

    private inner class View1ViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        var message: TextView = itemView.findViewById(R.id.textView)
        fun bind(position: Int) {
            val recyclerViewModel = list[position]
            message.text = recyclerViewModel.textData
        }
    }

    private inner class View2ViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        var message: TextView = itemView.findViewById(R.id.textView)
        fun bind(position: Int) {
            val recyclerViewModel = list[position]
            message.text = recyclerViewModel.textData
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == VIEW_TYPE_ONE) {
            return View1ViewHolder(
                LayoutInflater.from(context).inflate(R.layout.item_view_1, parent, false)
            )
        }
        return View2ViewHolder(
            LayoutInflater.from(context).inflate(R.layout.item_view_2, parent, false)
        )
    }

    override fun getItemCount(): Int {
        return list.size
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (list[position].viewType === VIEW_TYPE_ONE) {
            (holder as View1ViewHolder).bind(position)
        } else {
            (holder as View2ViewHolder).bind(position)
        }
    }

    override fun getItemViewType(position: Int): Int {
        return list[position].viewType
    }
}
Note: In the getItemViewType, we are returning the id of the view which is always unique.

Adding RecyclerView in our project

Now, add RecyclerView in the activity_main.xml. The following is the code for activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Now, the thing to do is just add the data to the views. The following is the code for MainActivity:

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val dataList = ArrayList<Data>()
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_ONE, "1. Hi! I am in View 1"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_TWO, "2. Hi! I am in View 2"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_ONE, "3. Hi! I am in View 3"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_TWO, "4. Hi! I am in View 4"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_ONE, "5. Hi! I am in View 5"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_TWO, "6. Hi! I am in View 6"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_ONE, "7. Hi! I am in View 7"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_TWO, "8. Hi! I am in View 8"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_ONE, "9. Hi! I am in View 9"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_TWO, "10. Hi! I am in View 10"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_ONE, "11. Hi! I am in View 11"))
        dataList.add(Data(RecyclerViewAdapter.VIEW_TYPE_TWO, "12. Hi! I am in View 12"))

        val adapter = RecyclerViewAdapter(this, dataList)
        recyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter
    }
}

Now, run the application on your device and you will see something like below:

RecyclerView Multiple View Types in Android

This is how you can implement multiple views in a RecyclerView. You can find the whole project from here.

I hope you enjoyed this blog. Do share this blog with your fellow developers to spread the knowledge.

Happy Learning :)

Team MindOrks!

Also, Let’s connect on Twitter, Linkedin, Github, and Facebook