RecyclerView Multiple View Types Example

This article helps you to integrate recyclerview with multiple view types in android applications through example.

I already explained you to how to implement recyclerview in android applications. In that example, Each row has same UI. So only one view type was used. But in this example we are implementing recyclerview with multiple view types.

Top soccer players names are displayed in this example. First we display club name as header in recycler view. Then we display player names associated with that particular club below the club name as items.

 
 

Add required dependency in app level build.gradle file

implementation ‘androidx.recyclerview:recyclerview:1.1.0’
 
 

Multiple Layouts For RecyclerView Multiple View Types

We need to create layout for every view type. So here we are creating two layouts. One for Club UI and other for Player UI.

 

header_view

<?xml version=”1.0″ encoding=”utf-8″?>
<androidx.constraintlayout.widget.ConstraintLayout     xmlns:android=”http://schemas.android.com/apk/res/android”
    android:layout_width=”match_parent”
    android:layout_height=”wrap_content”
    xmlns:app=”http://schemas.android.com/apk/res-auto”>

    <androidx.cardview.widget.CardView
        android:layout_width=”0dp”
        android:layout_height=”wrap_content”
        app:layout_constraintStart_toStartOf=”parent”
        app:layout_constraintEnd_toEndOf=”parent”
        app:layout_constraintTop_toTopOf=”parent”
        android:layout_marginHorizontal=”15dp”
        android:layout_marginVertical=”20dp”
        app:cardCornerRadius=”15dp”
        app:cardBackgroundColor=”@android:color/holo_red_dark”>

        <TextView
            android:id=”@+id/txt_club_name”
            android:layout_width=”wrap_content”
            android:layout_height=”wrap_content”
            android:layout_margin=”15dp”
            android:textSize=”25sp”
            android:textStyle=”bold”
            android:textColor=”@android:color/white” />

    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

 

item_view

<?xml version=”1.0″ encoding=”utf-8″?>
<androidx.constraintlayout.widget.ConstraintLayout    xmlns:android=”http://schemas.android.com/apk/res/android”
    android:layout_width=”match_parent”
    android:layout_height=”wrap_content”
    xmlns:app=”http://schemas.android.com/apk/res-auto”>

    <TextView
        android:id=”@+id/txt_player_name”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_marginHorizontal=”30dp”
        android:layout_marginVertical=”10dp”
        android:textSize=”22sp”
        app:layout_constraintStart_toStartOf=”parent”
        app:layout_constraintTop_toTopOf=”parent”/>

</androidx.constraintlayout.widget.ConstraintLayout>

 
 

Create Data Class

We need data class to differentiate each row view type. So we are passing view type and text name in data class.

data class PlayerData(val viewType: Int, val textName: String)
 
 

Create Adapter For RecyclerView Multiple View Types

We extend our adapter class to recyclerview adapter with custom view holder. But in this case we need to create two view holders for two view types. So we extend to recyclerview adapter with RecyclerView.ViewHolder type.

class PlayersAdapter(private val context: Context, private val listTopPlayers: MutableList<PlayerData>) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {

}

 
 

Create Multiple View Holders For RecyclerView Multiple View Types

We create one view holder for club view and other for player view.

class ClubsViewHolder(private val clubsView: View) : RecyclerView.ViewHolder(clubsView) {
        val txtClubName = clubsView.findViewById(R.id.txt_club_name) as TextView
}

class PlayersViewHolder(private val playersView: View) : RecyclerView.ViewHolder(playersView) {
        val txtPlayerName = playersView.findViewById(R.id.txt_player_name) as TextView
}

 
 

Integrate Multiple Layouts

companion object {
    const val CLUB_VIEW_TYPE = 1
    const val PLAYER_VIEW_TYPE = 2
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    if (viewType == CLUB_VIEW_TYPE) {
        return ClubsViewHolder(
            LayoutInflater.from(context).inflate(R.layout.header_view, parent, false)
        )
    } else {
        return PlayersViewHolder(
            LayoutInflater.from(context).inflate(R.layout.item_view, parent, false)
        )
    }
}

override fun getItemViewType(position: Int): Int {
    return listTopPlayers[position].viewType
}

 
 

Display Data

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    val itemData = listTopPlayers[position]
    if (itemData.viewType == CLUB_VIEW_TYPE) {
        val clubsViewHolder = holder as ClubsViewHolder
        clubsViewHolder.txtClubName.text = itemData.textName
    } else {
        val playersViewHolder = holder as PlayersViewHolder
        playersViewHolder.txtPlayerName.text = itemData.textName
    }
}
 
 

Add RecyclerView in Layout

<?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/recycler_soccer”
        android:layout_width=”0dp”
        android:layout_height=”0dp”
        android:text=”Hello World!”
        app:layout_constraintBottom_toBottomOf=”parent”
        app:layout_constraintLeft_toLeftOf=”parent”
        app:layout_constraintRight_toRightOf=”parent”
        app:layout_constraintTop_toTopOf=”parent”
        android:clipToPadding=”false”
        android:paddingBottom=”15dp”/>

</androidx.constraintlayout.widget.ConstraintLayout>

 
 

Integrate RecyclerView in Activity

class MainActivity : AppCompatActivity() {

private var listTopPlayers: MutableList<PlayerData> = mutableListOf<PlayerData>()
private var playersAdapter: PlayersAdapter? = null

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

    listTopPlayers = mutableListOf()

    listTopPlayers.add(PlayerData(PlayersAdapter.CLUB_VIEW_TYPE,”Real Madrid”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Sergio Ramos”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Karim Benzema”))
    listTopPlayers.add(PlayerData(PlayersAdapter.CLUB_VIEW_TYPE,”Barcelona”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Lionel Messi”))
    listTopPlayers.add(PlayerData(PlayersAdapter.CLUB_VIEW_TYPE,”Bayern Munich”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Robert Lewandowski”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Manuel Neuer”))
    listTopPlayers.add(PlayerData(PlayersAdapter.CLUB_VIEW_TYPE,”Manchester City”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Kevin De Bruyne”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Sergio Aguero”))
    listTopPlayers.add(PlayerData(PlayersAdapter.CLUB_VIEW_TYPE,”Paris Saint-Germain”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Neymar Jr.”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Kylian Mbappé”))
    listTopPlayers.add(PlayerData(PlayersAdapter.CLUB_VIEW_TYPE,”Liverpool”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Virgil van Dijk”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Mohamed Salah”))
    listTopPlayers.add(PlayerData(PlayersAdapter.PLAYER_VIEW_TYPE,”Sadio Mané”))

    recycler_soccer.layoutManager = LinearLayoutManager(this@MainActivity)
    playersAdapter = PlayersAdapter( this, listTopPlayers )
    recycler_soccer.adapter = playersAdapter

}
}

 
 

Final Code

package com.example.recyclerviewmultipleviewtypessample

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class PlayersAdapter(private val context: Context, private val listTopPlayers: MutableList<PlayerData>) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        const val CLUB_VIEW_TYPE = 1
        const val PLAYER_VIEW_TYPE = 2
    }

    class ClubsViewHolder(private val clubsView: View) : RecyclerView.ViewHolder(clubsView) {
        val txtClubName = clubsView.findViewById(R.id.txt_club_name) as TextView
    }

    class PlayersViewHolder(private val playersView: View) : RecyclerView.ViewHolder(playersView) {
        val txtPlayerName = playersView.findViewById(R.id.txt_player_name) as TextView
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == CLUB_VIEW_TYPE) {
            return ClubsViewHolder(
                LayoutInflater.from(context).inflate(R.layout.header_view, parent, false)
            )
        } else {
            return PlayersViewHolder(
                LayoutInflater.from(context).inflate(R.layout.item_view, parent, false)
            )
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val itemData = listTopPlayers[position]
        if (itemData.viewType == CLUB_VIEW_TYPE) {
            val clubsViewHolder = holder as ClubsViewHolder
            clubsViewHolder.txtClubName.text = itemData.textName
        } else {
            val playersViewHolder = holder as PlayersViewHolder
            playersViewHolder.txtPlayerName.text = itemData.textName
        }
    }

    override fun getItemViewType(position: Int): Int {
        return listTopPlayers[position].viewType
    }

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

}
 
 
 
recyclerview multiple view types example
 
 
 

Leave a Reply