How to write a RecyclerView Adapter with Heterogeneous Data in Android

Ivan Terekhin
2 min readApr 18, 2023

--

To write a RecyclerView adapter with heterogeneous data like “cards” and “entries”, you can create a base class for your data items and then create subclasses for each type of item.

To handle heterogeneous data, we need a common interface or base class that all the data items will implement or extend. In this case, we will create a base class for our data items and define an abstract method to get the type of the item. Let’s create a base class:

abstract class BaseItem {
abstract fun getType(): Int
}

And our “card” and “entry” classes:

class CardItem : BaseItem() {
override fun getType(): Int {
return 0
}
}

class EntryItem : BaseItem() {
override fun getType(): Int {
return 1
}
}

Now, we can create a RecyclerView adapter that can handle multiple types of items. In the adapter’s onCreateViewHolder() method, we can inflate the correct layout based on the item type. In the onBindViewHolder() method, we can cast the BaseItem to the appropriate subclass and bind the data to the views. Here it is:

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

override fun getItemViewType(position: Int): Int {
return items[position].getType()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return when (viewType) {
0 -> {
val view = inflater.inflate(R.layout.card_item, parent, false)
CardViewHolder(view)
}
1 -> {
val view = inflater.inflate(R.layout.entry_item, parent, false)
EntryViewHolder(view)
}
else -> throw IllegalArgumentException("Invalid view type")
}
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = items[position]
when (item.getType()) {
0 -> {
val cardItem = item as CardItem
val cardViewHolder = holder as CardViewHolder
// bind data to cardViewHolder views
}
1 -> {
val entryItem = item as EntryItem
val entryViewHolder = holder as EntryViewHolder
// bind data to entryViewHolder views
}
}
}

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

inner class CardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
// views
}

inner class EntryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
// views
}
}

So, as you can see, nothing hard or something like that. Pretty straightforward. Hopefully, it will be useful for someone. :)

--

--

Ivan Terekhin
Ivan Terekhin

Written by Ivan Terekhin

Mobile developer (Android, iOS, Flutter), AI and GameDev enthusiast. https://www.indiehackers.com/jeuler

No responses yet