A simple way to create different view types in RecyclerView Android

Learn how to create a RecyclerView with multiple type of layouts.

Rohail Ahmad
3 min readAug 5, 2020

If your app needs to display a scrolling list of elements based on large data sets (or data that frequently changes), you should use RecyclerView

The RecyclerView widget is a more advanced and flexible version of ListView.
In the RecyclerView model, several different components work together to display your data. The overall container for your user interface is a RecyclerView object that you add to your layout. The RecyclerView fills itself with views provided by a layout manager that you provide. You can use one of the standard layout managers (such as LinearLayoutManager or GridLayoutManager), or implement your own.

Add the support library

To access the RecyclerView widget, you need to add the v7 Support Libraries to your project as follows:

  1. Open the build.gradle file for your app module.
  2. Add the support library to the dependencies section.
dependencies {
implementation 'com.android.support:recyclerview-v7:28.0.0'
}

Add RecyclerView to your layout

Now you can add the RecyclerView to your layout file. For example, the following layout uses RecyclerView as the only view for the whole layout:

<?xml version="1.0" encoding="utf-8"?>
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

Once you have added a RecyclerView widget to your layout, obtain a handle to the object, connect it to a layout manager, and attach an adapter for the data to be displayed:

class MyActivity : Activity(), OnListActivityInteractionListener {
private lateinit var recyclerView: RecyclerView
private lateinit var viewAdapter: RecyclerView.Adapter<*>
private lateinit var viewManager: RecyclerView.LayoutManager

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

viewManager = LinearLayoutManager(this)
viewAdapter = MyAdapter(myDataset, this)

recyclerView = findViewById<RecyclerView>(R.id.my_recycler_view).apply {
// use this setting to improve performance if you know that changes

// use a linear layout manager
layoutManager = viewManager

// specify an viewAdapter (see also next example)
adapter = viewAdapter

}
}
}

Interface

interface OnListActivityInteractionListener {
fun onListFragmentInteraction(item: Item)
}

Add a list adapter

To feed all your data to the list, you must extend the RecyclerView.Adapter class. This object creates views for items, and replaces the content of some of the views with new data items when the original item is no longer visible.

The following code example shows a simple implementation for a data set that consists of an array of strings displayed using TextView widgets:

class MyAdapter(private val myDataset: List<Item>,
private val mListener: OnListActivityInteractionListener) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {

private val mOnClickListener: View.OnClickListener

init {
mOnClickListener = View.OnClickListener { v ->
val item = v.tag as Item
mListener.onListActivityInteraction(item)
}
}
//view types
companion object {
const val HEADER = 1
const val CHILD = 2
}


// Return the size of your dataset (invoked by the layout manager)
override fun getItemCount() = myDataset.size
}

Item data class

data class Item(
val name: String,
val value: String
)

getItemViewType

override fun getItemViewType(position: Int): Int {
return when (myDataset[position].value) {
"HEADING" -> HEADER
else -> CHILD
}
}

onCreateViewHolder

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view: View
when (viewType) {
HEADER -> {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.header_item, parent, false)
return HeaderViewHolder(view)
}
CHILD -> {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.child_item, parent, false)
return ChildViewHolder(view)
}
else -> {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.empty, parent, false)
return HeaderViewHolder(view)
}
}
}

onBindViewHolder

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {

val item = myDataset[position]
when (getItemViewType(position)) {
HEADER -> (holder as HeaderViewHolder).textView.text = item.name
CHILD -> {
val viewHolder =
(holder as ChildViewHolder)
viewHolder.textView.text = item.name

with(viewHolder.mView) {
tag = item
setOnClickListener(mOnClickListener)
}

}
}
}

HeaderViewHolder & ChildViewHolder

inner class HeaderViewHolder(mView: View) : RecyclerView.ViewHolder(mView) {
val textView: AppCompatTextView = mView.tvTitle
}

inner class ChildViewHolder(val mView: View) : RecyclerView.ViewHolder(mView) {
val textView: AppCompatTextView = mView.tvName
}

Final result

I hope you have an idea of how to implement multiple view types in RecyclerView together with click listener. You can change views and do how you like.

If you enjoyed this article then smash the applause icon a couple of times for appreciation.

--

--

Rohail Ahmad

Android Engineer with @kivrasweden formerly @Eliq & @Inov8