A Step-by-Step Guide on How to Create Different View Types for RecyclerView with Kotlin in Android
RecyclerView is one of the most commonly used UI components in Android
applications for displaying a list of data items. In many cases, we need to
display different types of items in the same list, such as images, text, and
buttons.
Creating different view types with Kotlin in Android can be a challenging
task. But with the right steps and tools, it is possible to create multiple
view types for your app's RecyclerView and ListViews. In this guide, we will
walk you through the process of creating multiple view types with Kotlin in
Android, from setting up the project to creating a RecyclerView adapter and a
ListView adapter. We will also discuss some of the use cases of creating
multiple views so that you can make an informed decision on how to best
utilize this powerful feature in your Android application.
Before we start, check our other articles on RecyclerView
In this blog, we will learn how to implement multiple view types in
RecyclerView using Kotlin.
RecyclerView provides a way to display multiple view types in the same list.
This can be achieved by creating multiple ViewHolder classes and overriding
the
getItemViewType
method in your
RecyclerView adapter.
To implement multiple view types in RecyclerView, you need to perform the
following steps:
1. Define the Data Model Classes
Create a data class for each type of view that you want to display. Each
data class should extend a common base data class, which will be used to
identify the view type.
sealed class ListItem { data class HeaderItem(val text: String) : ListItem() data class TextItem(val text: String) : ListItem() data class ImageItem(val imageUrl: String) : ListItem() }
2. Create ViewHolder classes for each view type
Create a separate
ViewHolder
class for each view type you want to display in the RecyclerView. A
ViewHolder is responsible for holding the references to the views for a
particular item in the list.
Here, I'm using Glide to load images from the internet and display them in
our list
// ViewHolder classes for each type of view class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(item: ListItem.HeaderItem) { // Bind data to views val textView = itemView.findViewById<TextView>(R.id.text_view) textView.text = item.header } } class TextViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(item: ListItem.TextItem) { // Bind data to views val textView = itemView.findViewById<TextView>(R.id.text_view) textView.text = item.text } } class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(item: ListItem.ImageItem) { // Bind data to views val imageView = itemView.findViewById<ImageView>(R.id.imageView) GlideApp.with(imageView) .load(item.imageUrl) .into(imageView) } }
3. Create a RecyclerView adapter
Create an adapter class that extends the
RecyclerView.Adapter
class and override the below methods:
- onCreateViewHolder: This method is called when the RecyclerView needs a new ViewHolder of a given type to represent an item. In this method, you need to create and return a new ViewHolder object for the specified view type.
- onBindViewHolder: This method is called to bind the data to the ViewHolder. In this method, you need to bind the data to the ViewHolder based on the view type.
- getItemCount: This method returns the total number of items in the RecyclerView.
-
getItemViewType: Override the
getItemViewType
method of the RecyclerView.Adapter class to return the view type of the item at the specified position.
class MyAdapter( private val items: List<ListItem> ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { // ViewHolder classes for each type of view inner class HeaderViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(item: ListItem.HeaderItem) { // Bind data to views val textView = itemView.findViewById<TextView>(R.id.text_view) textView.text = item.header } } inner class TextViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(item: ListItem.TextItem) { // Bind data to views val textView = itemView.findViewById<TextView>(R.id.text_view) textView.text = item.text } } inner class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(item: ListItem.ImageItem) { // Bind data to views val imageView = itemView.findViewById<ImageView>(R.id.imageView) GlideApp.with(imageView) .load(item.imageUrl) .into(imageView) } } override fun getItemViewType(position: Int): Int { return when (items[position]) { is ListItem.HeaderItem -> 0 is ListItem.TextItem -> 1 is ListItem.ImageItem -> 2 } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { 0 -> HeaderViewHolder( LayoutInflater.from(parent.context) .inflate(R.layout.header_item_layout, parent, false) ) 1 -> TextViewHolder( LayoutInflater.from(parent.context) .inflate(R.layout.text_item_layout, parent, false) ) 2 -> ImageViewHolder( LayoutInflater.from(parent.context) .inflate(R.layout.image_item_layout, parent, false) ) else -> throw IllegalArgumentException("Invalid view type") } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (val item = items[position]) { is ListItem.HeaderItem -> (holder as HeaderViewHolder).bind(item) is ListItem.TextItem -> (holder as TextViewHolder).bind(item) is ListItem.ImageItem -> (holder as ImageViewHolder).bind(item) } } override fun getItemCount() = items.size }
4. Create custom layout files
Create layout files for each type of view that you want to display.
header_item_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" android:paddingHorizontal="10dp" android:background="@color/teal_700" android:paddingVertical="4dp"> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:textColor="@color/black" android:textSize="20sp" android:textStyle="bold" tools:text="@tools:sample/first_names" /> </LinearLayout>
text_item_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" android:paddingHorizontal="10dp" android:background="@color/teal_700" android:paddingVertical="4dp"> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:textColor="@color/black" android:textSize="20sp" android:textStyle="bold" tools:text="@tools:sample/first_names" /> </LinearLayout>
image_item_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" android:paddingHorizontal="10dp" android:background="@color/teal_700" android:paddingVertical="4dp"> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/text_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:textColor="@color/black" android:textSize="20sp" android:textStyle="bold" tools:text="@tools:sample/first_names" /> </LinearLayout>
5. Set the adapter for RecyclerView
Finally, create an instance of the adapter in your activity or fragment and
set it to your RecyclerView.
fun setupRecyclerview(){ val recyclerView = findViewById<RecyclerView>(R.id.my_recycler_view) val list = listOf( ListItem.HeaderItem("Header 1"), ListItem.TextItem("Text Item 1"), ListItem.TextItem("Text Item 2"), ListItem.ImageItem("https://loremflickr.com/320/240"), ListItem.HeaderItem("Header 2"), ListItem.TextItem("Text Item 3"), ListItem.TextItem("Text Item 4"), ListItem.ImageItem("https://loremflickr.com/320/240"), ListItem.HeaderItem("Header 3"), ListItem.ImageItem("https://loremflickr.com/320/240"), ListItem.ImageItem("https://loremflickr.com/320/240"), ) val adapter = MyAdapter(list) recyclerView.layoutManager = LinearLayoutManager(context) recyclerView.adapter = adapter }
And that's it! You should now have a working RecyclerView in Kotlin with
multiple view types.
In conclusion, the use of RecyclerView with multiple view types is a great
way to display data efficiently in an Android application. By using Kotlin,
developers can quickly and easily create custom views and adapters for their
RecyclerView.
In this article, we discussed the use of RecyclerView in Android
applications with Kotlin. We also looked at how to create multiple view
types with RecyclerView using Kotlin. We hope this article has given you a
better understanding of how to implement a
RecyclerView with Kotlin
and how to use multiple view types for different kinds of data in an Android
application.