Looking For Anything Specific?

How To Create RecyclerView With Multiple View Types In Kotlin

 Hello There,

We have been posting a tutorial about how to create a recycler view in android in the previous tutorial and set a click listener to recycler view list item, In this part of the tutorial we are going to share you how to create a recycler view with multiple view types, So if you're not following those previous tutorials you can read them below 

Now, Come back to this tutorial on how to set up multiple view types to recycler view, In General RecyclerView requires a layout / View to show the components on to the screen for which we give them a ViewHolder,  But the ViewHolder is bound to using only one layout what if we what to use a more than one type of layout, and that is what we are going to look into today.

You can learn more about android recyclerview here: Android RecyclerView

android studio recyclerview multiple view type
File and Folder Structure for Multiple View Type 

 In order to give multiple view types to a recycler view, we have to create two view types which are a combination of two layouts and two view holders for recycler view so then we can use them to show different layouts based on our requirements.

Android Kotlin Tutorial On How to Pass Data Between Activities

Creating Multiple View Types For Recycler View:

Let's start with creating layout files Click the Layout folder in your android studio project structure and create a Layout file with the name as row_item_with_button and make sure the root is set to constraint layout because it is one of the advanced layout available in android for designing, you can copy the below code to use as a first view type 


<?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_margin="8dp"
    android:background="@drawable/square_corner"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="32dp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

After creating your first view type do the above process again and create a second view type by creating a new layout file named row_item_with_button 


<?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:background="@drawable/rounded_corner"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:text="TextView"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Both the above layout will be the multiple view types that we will be using in our Recycler View in order to show different layouts in a recycler view that is a very good feature that will be helpful in many cases 

Learn How To Ask Runtime Permission In Android With Kotlin

Create RecyclerView Adapter for Multiple View Type : 

If we want to make our recycler view to work properly we have to need an adapter that handles the process of creating and destroying views and show the data we want. You can learn more about the RecyclerView adapter in our basics tutorial Here. For now, we are going to focus on how to create a recycler view adapter that can be used with multiple layouts, for that we need to do pre-setup first, which is creating the view holder, In a recycler view if we want to show multiple view type/ layouts we need to have multiple RecyclerView ViewHolder so that our code will not look messy 

Create Multiple View Holder For RecyclerView Adapter :

Create two new kotlin class files which will be the ViewHolders for the multiple layouts. Name the files same as the layout name to avoid confusion like Below, 

ViewHolder for first layout row_item_with_button  as RowItemWithButtonViewHolder it is also a best practice to  end files named with its purposes like ViewHolder Adapter, Fragment, or Activity 



class RowItemWithButtonViewHolder (val view: View):RecyclerView.ViewHolder(view){
    private val textView: TextView = view.findViewById(R.id.textView)
    private val button: Button = view.findViewById(R.id.button)

    fun bind(position: Int) {
        textView.text = "$position"
        button.text = "$position"
    }

}

Now create our second ViewHolder for the second layout file follow the same naming convention for files, so for this layout row_item_without_button it will be like RowItemWithoutButton


class RowItemWithoutButtonViewHolder (val view: View):RecyclerView.ViewHolder(view){
    private val textView2 :TextView = view.findViewById(R.id.textView2)
    fun bind(position: Int) {
        textView2.text = "$position"
    }

}

Pro Tip: While copy-pasting code if you see missing imports, simply put the cursor on the class name and press control enter to automatically import missing classes

Now that we have two ViewHolders for our two layouts we can make changes to our adapter this tutorial is completely based on Kotlin but these classes were the as creating them in Java as well, So to make our recycler view adapter accept multiple ViewHolders we have to extend the class with RecyclerView.Adapter and then mention the type as RecyclerView.ViewHolder instead of a single ViewHolder, like below 


class MultiTypeRecyclerViewAdapter():RecyclerView.Adapter<RecyclerView.ViewHolder>(){
}

Like this is how the recycler view adapter has to be defined so that the override functions will return a RecyclerView ViewHolder instead of a different class or a single view holder class like we did in our first tutorial once you define like this we have to add the necessary override functions like onCreateView, getItemCount and onBindViewHolder these are the default functions to be implemented if we want our recycler view to work with a single layout and a  view holder but if we want to add more than one layout to a RecyclerView we have to override one more function which is getItemViewType(position: Int): Int which returns an integer value representing the view type in that function we have to add our own login to define the view type, below is the complete code for android recyclerview multiple view types in kotlin   


class MultiTypeRecyclerViewAdapter():RecyclerView.Adapter<RecyclerView.ViewHolder>(){
    val TYPE_A = 1
    val TYPE_B = 2
    override fun getItemViewType(position: Int): Int {
        return if(position %2 ==0){
            TYPE_A
        }else{
            TYPE_B
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return if(viewType == TYPE_A){
            RowItemWithButtonViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_item_with_button,parent,false))
        }else{
            RowItemWithoutButtonViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_item_without_button,parent,false))
        }
    }

    override fun getItemCount(): Int = 10

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when(holder){
            is RowItemWithButtonViewHolder -> {
                holder.bind(position)
            }
            is RowItemWithoutButtonViewHolder ->{
                holder.bind(position)
            }
        }
    }

}

In the above code, we defined two variables TYPE_A and TYPE_B to define the type of view we want, and in the getItemViewType function we return the view type based on a little login which is to return TYPE_A if the position is even number and TYPE_B if the position is an odd number, this function will be called before onCreateView so the view type view will be set before it's even created now when the onCreateViewHolder is called we check the view type variable to the matching view type, we return the appropriate view holder to display in the view.

Now after creating the view, after onCreateViewHolder is called, then the android system will call onBindViewHolder, in where we pass the data we want to pass to our layout, previously we created a bind function in both the ViewHolders to show the position of the layout, In order to call the correct Viewholder we have to make sure that we are calling the right view holder for that we have to typecast the ViewHolder to our class and it is made easy with Kotlin, In Kotlin we if we check the type of a variable with `is` keyword it will automatically typecast the variable inside the block, by this way it will only call the appropriate functions.

Sample Output 

android recyclerview multiple view type example kotlin


With everything covered I hope this will be enough to create a recycler view with multiple view types in kotlin, which require multiple layouts and multiple view holders and the key to achieve a perfect multiple view holder pattern in android recycler view is to properly use the getItemViewType function to return the proper variable we want so that it can be used with.


For differentiation, we have added some extra effects to the layout a rounded corner and a square corner you can learn more about them below 


Thanks for reading 


!!!SHARING IS CARING!!!


keywords:

android recyclerview with multiple views github

recyclerview multiple adapters

recyclerview with multiple sections

how to use multiple recyclerview in android

recyclerview multiple view types kotlin

recyclerview with multiple arraylist android

recyclerview android

how to inflate layout in recyclerview


Post a Comment

1 Comments

Have doubts? Shoot your thoughts....