Android RecyclerView Multiple Layout Sealed Class

Item.kt, the sealed class with two item types. A list of Items will be created but with different item types, either ItemOne or ItemTwo, but it will be a list of Items to be passed to the RecyclerView adapter.

sealed class Item()
class ItemOne(var name: String = "") : Item()
class ItemTwo(var name: String = "") : Item()

MainActivity.kt, the main class that creates the sample data for the recycerview.

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*

import java.util.ArrayList

class MainActivity : AppCompatActivity() {

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

        // Initializing list view with the custom adapter
        val itemList = ArrayList()
        val itemArrayAdapter = ItemArrayAdapter(itemList)
        item_list.layoutManager = LinearLayoutManager(this)
        item_list.itemAnimator = DefaultItemAnimator()
        item_list.adapter = itemArrayAdapter

        // Populating list items
        for (i in 0..99) {
            if (i % 2 == 0) {
                itemList.add(ItemOne("Item " + i))
            } else {
                itemList.add(ItemTwo("Item " + i))
            }
        }
    }
}

ItemArrayAdapter.kt, in the getItemViewType, it checks the type of the items, and it is being used to determine which layout to use.

import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import java.util.ArrayList

class ItemArrayAdapter(private val itemList: ArrayList = ArrayList()) : RecyclerView.Adapter() {

    // get the size of the list
    override fun getItemCount(): Int = itemList.size

    // determine which layout to use for the row
    override fun getItemViewType(position: Int): Int {
        val item = itemList[position]
        return when (item) {
            is ItemOne -> TYPE_ONE
            is ItemTwo -> TYPE_TWO
        }
    }

    // specify the row layout file and click for each row
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == TYPE_ONE) {
            val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item_type1, parent, false)
            return ViewHolderOne(view)
        } else if (viewType == TYPE_TWO) {
            val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item_type2, parent, false)
            return ViewHolderTwo(view)
        } else {
            throw RuntimeException("The type has to be ONE or TWO")
        }
    }

    // load data in each row element
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, listPosition: Int) {
        when (holder.itemViewType) {
            TYPE_ONE -> initLayoutOne(holder as ViewHolderOne, listPosition)
            TYPE_TWO -> initLayoutTwo(holder as ViewHolderTwo, listPosition)
            else -> {
            }
        }
    }

    private fun initLayoutOne(holder: ViewHolderOne, pos: Int) {
        val item = itemList[pos] as ItemOne
        holder.item.text = item.name
    }

    private fun initLayoutTwo(holder: ViewHolderTwo, pos: Int) {
        val item = itemList[pos] as ItemTwo
        holder.tvLeft.text = item.name
        holder.tvRight.text = item.name
    }

    // Static inner class to initialize the views of rows
    internal class ViewHolderOne(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var item: TextView
        init {
            item = itemView.findViewById(R.id.row_item) as TextView
        }
    }

    inner class ViewHolderTwo(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var tvLeft: TextView
        var tvRight: TextView

        init {
            tvLeft = itemView.findViewById(R.id.row_item_left) as TextView
            tvRight = itemView.findViewById(R.id.row_item_right) as TextView
        }
    }

    companion object {
        private val TYPE_ONE = 1
        private val TYPE_TWO = 2
    }
}

activity_main.xml


    

list_item_type1.xml



    

list_item_type2.xml



    
    

Complete example in Github

Search within Codexpedia

Custom Search

Search the entire web

Custom Search