Recyclerview with Multiple View Types in Kotlin for Android

A Step-by-Step Guide on How to Create Different View Types for RecyclerView with Kotlin in Android

RecyclerView is one of the most commonly used UI components in Android applications for displaying a list of data items. In many cases, we need to display different types of items in the same list, such as images, text, and buttons. 

Creating different view types with Kotlin in Android can be a challenging task. But with the right steps and tools, it is possible to create multiple view types for your app's RecyclerView and ListViews. In this guide, we will walk you through the process of creating multiple view types with Kotlin in Android, from setting up the project to creating a RecyclerView adapter and a ListView adapter. We will also discuss some of the use cases of creating multiple views so that you can make an informed decision on how to best utilize this powerful feature in your Android application.

In this blog, we will learn how to implement multiple view types in RecyclerView using Kotlin.

Android Recyclerview with multiple view types in kotlin

RecyclerView provides a way to display multiple view types in the same list. This can be achieved by creating multiple ViewHolder classes and overriding the getItemViewType method in your RecyclerView adapter.

To implement multiple view types in RecyclerView, you need to perform the following steps:

1. Define the Data Model Classes

Create a data class for each type of view that you want to display. Each data class should extend a common base data class, which will be used to identify the view type.

sealed class ListItem {
    data class HeaderItem(val text: String) : ListItem()
    data class TextItem(val text: String) : ListItem()
    data class ImageItem(val imageUrl: String) : ListItem()
}

2. Create ViewHolder classes for each view type

Create a separate ViewHolder class for each view type you want to display in the RecyclerView. A ViewHolder is responsible for holding the references to the views for a particular item in the list.

Here, I'm using Glide to load images from the internet and display them in our list

// ViewHolder classes for each type of view
    class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: ListItem.HeaderItem) {
            // Bind data to views
            val textView = itemView.findViewById<TextView>(R.id.text_view)
            textView.text = item.header
        }
    }

    class TextViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: ListItem.TextItem) {
            // Bind data to views
            val textView = itemView.findViewById<TextView>(R.id.text_view)
            textView.text = item.text
        }
    }

    class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: ListItem.ImageItem) {
            // Bind data to views
            val imageView = itemView.findViewById<ImageView>(R.id.imageView)
            GlideApp.with(imageView)
                .load(item.imageUrl)
                .into(imageView)
        }
    }

3. Create a RecyclerView adapter 

Create an adapter class that extends the RecyclerView.Adapter class and override the below methods:
  • onCreateViewHolder: This method is called when the RecyclerView needs a new ViewHolder of a given type to represent an item. In this method, you need to create and return a new ViewHolder object for the specified view type.
  • onBindViewHolder: This method is called to bind the data to the ViewHolder. In this method, you need to bind the data to the ViewHolder based on the view type.
  • getItemCount: This method returns the total number of items in the RecyclerView.
  • getItemViewType: Override the getItemViewType method of the RecyclerView.Adapter class to return the view type of the item at the specified position.

class MyAdapter(
    private val items: List<ListItem>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    // ViewHolder classes for each type of view
    inner class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: ListItem.HeaderItem) {
            // Bind data to views
            val textView = itemView.findViewById<TextView>(R.id.text_view)
            textView.text = item.header
        }
    }

    inner class TextViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: ListItem.TextItem) {
            // Bind data to views
            val textView = itemView.findViewById<TextView>(R.id.text_view)
            textView.text = item.text
        }
    }

    inner class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(item: ListItem.ImageItem) {
            // Bind data to views
            val imageView = itemView.findViewById<ImageView>(R.id.imageView)
            GlideApp.with(imageView)
                .load(item.imageUrl)
                .into(imageView)
        }
    }

    override fun getItemViewType(position: Int): Int {
        return when (items[position]) {
            is ListItem.HeaderItem -> 0
            is ListItem.TextItem -> 1
            is ListItem.ImageItem -> 2
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            0 -> HeaderViewHolder(
                LayoutInflater.from(parent.context)
                    .inflate(R.layout.header_item_layout, parent, false)
            )
            1 -> TextViewHolder(
                LayoutInflater.from(parent.context)
                    .inflate(R.layout.text_item_layout, parent, false)
            )
            2 -> ImageViewHolder(
                LayoutInflater.from(parent.context)
                    .inflate(R.layout.image_item_layout, parent, false)
            )
            else -> throw IllegalArgumentException("Invalid view type")
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (val item = items[position]) {
            is ListItem.HeaderItem -> (holder as HeaderViewHolder).bind(item)
            is ListItem.TextItem -> (holder as TextViewHolder).bind(item)
            is ListItem.ImageItem -> (holder as ImageViewHolder).bind(item)
        }
    }

    override fun getItemCount() = items.size
}

4. Create custom layout files 

Android Recyclerview with multiple view types in kotlin

Create layout files for each type of view that you want to display.

header_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:paddingHorizontal="10dp"
    android:background="@color/teal_700"
    android:paddingVertical="4dp">

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:textColor="@color/black"
        android:textSize="20sp"
        android:textStyle="bold"
        tools:text="@tools:sample/first_names" />
</LinearLayout>

text_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:paddingHorizontal="10dp"
    android:background="@color/teal_700"
    android:paddingVertical="4dp">

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:textColor="@color/black"
        android:textSize="20sp"
        android:textStyle="bold"
        tools:text="@tools:sample/first_names" />
</LinearLayout>

image_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:paddingHorizontal="10dp"
    android:background="@color/teal_700"
    android:paddingVertical="4dp">

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:textColor="@color/black"
        android:textSize="20sp"
        android:textStyle="bold"
        tools:text="@tools:sample/first_names" />
</LinearLayout>

5. Set the adapter for RecyclerView

Finally, create an instance of the adapter in your activity or fragment and set it to your RecyclerView.
fun setupRecyclerview(){
    val recyclerView = findViewById<RecyclerView>(R.id.my_recycler_view)
    val list = listOf(
        ListItem.HeaderItem("Header 1"),
        ListItem.TextItem("Text Item 1"),
        ListItem.TextItem("Text Item 2"),
        ListItem.ImageItem("https://loremflickr.com/320/240"),
        ListItem.HeaderItem("Header 2"),
        ListItem.TextItem("Text Item 3"),
        ListItem.TextItem("Text Item 4"),
        ListItem.ImageItem("https://loremflickr.com/320/240"),
        ListItem.HeaderItem("Header 3"),
        ListItem.ImageItem("https://loremflickr.com/320/240"),
        ListItem.ImageItem("https://loremflickr.com/320/240"),
    )
    
    val adapter = MyAdapter(list)
    recyclerView.layoutManager = LinearLayoutManager(context)
    recyclerView.adapter = adapter
}

And that's it! You should now have a working RecyclerView in Kotlin with multiple view types.

RecyclerView with multiple view types with Kotlin in Android


In conclusion, the use of RecyclerView with multiple view types is a great way to display data efficiently in an Android application. By using Kotlin, developers can quickly and easily create custom views and adapters for their RecyclerView. 

In this article, we discussed the use of RecyclerView in Android applications with Kotlin. We also looked at how to create multiple view types with RecyclerView using Kotlin. We hope this article has given you a better understanding of how to implement a RecyclerView with Kotlin and how to use multiple view types for different kinds of data in an Android application.

Thanks for reading this article. Hope you would have liked it!. Please share and subscribe to my blog to support.

Pragnesh Ghoda

A forward-thinking developer offering more than 8 years of experience building, integrating, and supporting android applications for mobile and tablet devices on the Android platform. Talks about #kotlin and #android

Post a Comment

Please let us know about any concerns or query.

Previous Post Next Post

Contact Form