Open In App

How to Add Dividers in Android RecyclerView?

Improve
Improve
Like Article
Like
Save
Share
Report

In the article Android RecyclerView in Kotlin, it’s been demonstrated how to implement the RecyclerView in Android. But in the case of User Experience, the items need to be distinguished with the divider and proper padding and margins in each item. In this case, the RecyclerView ItemDecoration comes into the picture. So, in this its been demonstrated how to make actually use the RecyclerView ItemDecoration and use the dividers and custom dividers in between RecyclerView Items. Have a look at the following image to get an overview of the entire discussion.

Add Dividers in Android RecyclerView

Create an empty activity project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.

Add Required Dependency

Include google material design components dependency in the build.gradle file. After adding the dependencies don’t forget to click on the “Sync Now” button present at the top right corner.

implementation “androidx.recyclerview:recyclerview:1.2.1”

Note that while syncing the project you need to be connected to the network and make sure that you are adding the dependency to the app-level Gradle file as shown below.

Steps to implement Item Decoration in RecyclerView

Step 1: Working with activity_main.xml file

The main layout of the project contains one RecyclerView for demonstration purposes. To implement the same invoke the following code inside the activity_main.xml file.

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
  
</androidx.constraintlayout.widget.ConstraintLayout>


Before going to the output we need to populate the RecyclerView with the data. So we need to now work with RecyclerView Adapter and a custom view for the RecyclerView.

Step 2: Create a custom view for RecyclerView

The custom view for the RecyclerView contains one simple icon at the left and two TextViews. To implement the same create a file named recycler_data_view.xml inside the layout folder and invoke the following code.

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="16dp">
  
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="54dp"
        android:layout_height="54dp"
        android:src="@drawable/ic_android"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  
    <TextView
        android:id="@+id/tvNumber"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/tvNumbersInText"
        app:layout_constraintStart_toEndOf="@+id/imageView"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="1" />
  
    <TextView
        android:id="@+id/tvNumbersInText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="@+id/tvNumber"
        app:layout_constraintTop_toBottomOf="@+id/tvNumber"
        tools:text="One" />
  
</androidx.constraintlayout.widget.ConstraintLayout>


The above custom view produces the following output for each item in the list:

Step 3: Creating Data Class for RecyclerView

Now creating the data for the above custom view by creating a Data Class, using the following code.

Kotlin




data class RecyclerViewData(
    val text1: String,
    val text2: String
)


Step 4: Creating the RecyclerView Adapter

The following code needs to invoke in a separate class by creating the class named as MyRecyclerAdapter.

Kotlin




import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
  
class MyRecyclerViewAdapter(private val items: List<RecyclerViewData>) :
    RecyclerView.Adapter<MyRecyclerViewAdapter.MyRecyclerViewDataHolder>() {
  
    inner class MyRecyclerViewDataHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
  
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyRecyclerViewDataHolder {
        val view: View =
            LayoutInflater.from(parent.context).inflate(R.layout.recycler_data_view, parent, false)
        return MyRecyclerViewDataHolder(view)
    }
  
    override fun onBindViewHolder(holder: MyRecyclerViewDataHolder, position: Int) {
        val currentItem: RecyclerViewData = items[position]
  
        val tvNumber: TextView = holder.itemView.findViewById(R.id.tvNumber)
        tvNumber.text = currentItem.text1
  
        val tvNumbersInText: TextView = holder.itemView.findViewById(R.id.tvNumbersInText)
        tvNumbersInText.text = currentItem.text2
    }
  
    override fun getItemCount(): Int {
        return items.size
    }
}


Step 5: Working with the MainActivity.kt file

In this class, we have to create some sample data for the RecyclerView in the form of a list. To implement the same invoke the following code inside the MainActivity.kt file (comments are added for better understanding).

Kotlin




package com.adityamshidlyali.gfgautohidefab
  
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
  
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // create instance of RecyclerView 
        // and register with the appropriate ID
        val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
  
        // create list of RecyclerViewData
        var recyclerViewData = listOf<RecyclerViewData>()
        recyclerViewData = recyclerViewData + RecyclerViewData("1", "One")
        recyclerViewData = recyclerViewData + RecyclerViewData("2", "Two")
        recyclerViewData = recyclerViewData + RecyclerViewData("3", "Three")
        recyclerViewData = recyclerViewData + RecyclerViewData("4", "Four")
        recyclerViewData = recyclerViewData + RecyclerViewData("5", "Five")
        recyclerViewData = recyclerViewData + RecyclerViewData("6", "Six")
        recyclerViewData = recyclerViewData + RecyclerViewData("7", "Seven")
        recyclerViewData = recyclerViewData + RecyclerViewData("8", "Eight")
        recyclerViewData = recyclerViewData + RecyclerViewData("9", "Nine")
        recyclerViewData = recyclerViewData + RecyclerViewData("10", "Ten")
        recyclerViewData = recyclerViewData + RecyclerViewData("11", "Eleven")
        recyclerViewData = recyclerViewData + RecyclerViewData("12", "Twelve")
        recyclerViewData = recyclerViewData + RecyclerViewData("13", "Thirteen")
        recyclerViewData = recyclerViewData + RecyclerViewData("14", "Fourteen")
        recyclerViewData = recyclerViewData + RecyclerViewData("15", "Fifteen")
  
        // create a vertical layout manager
        val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
  
        // create instance of MyRecyclerViewAdapter
        val myRecyclerViewAdapter = MyRecyclerViewAdapter(recyclerViewData)
  
        // attach the adapter to the recycler view
        recyclerView.adapter = myRecyclerViewAdapter
  
        // also attach the layout manager
        recyclerView.layoutManager = layoutManager
  
        // make the adapter the data set
        // changed for the recycler view
        myRecyclerViewAdapter.notifyDataSetChanged()
    }
}


Output:

Creating the default divider for the items in RecyclerView

We have to create a default Divider using addItemDecoration() method with the RecyclerView instance, we need to pass the ItemDecoration(in this case it is DividerItemDecoration()) instance and the orientation of the LayoutManager(in this case it is vertical) of the recycler view. To implement the same invoke the following code inside the MainActivity.kt file(Comments are added for better understanding).

Kotlin




import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
  
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // create instance of RecyclerView and register with the appropriate ID
        val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
  
        // create list of RecyclerViewData
        var recyclerViewData = listOf<RecyclerViewData>()
        recyclerViewData = recyclerViewData + RecyclerViewData("1", "One")
        recyclerViewData = recyclerViewData + RecyclerViewData("2", "Two")
        recyclerViewData = recyclerViewData + RecyclerViewData("3", "Three")
        recyclerViewData = recyclerViewData + RecyclerViewData("4", "Four")
        recyclerViewData = recyclerViewData + RecyclerViewData("5", "Five")
        recyclerViewData = recyclerViewData + RecyclerViewData("6", "Six")
        recyclerViewData = recyclerViewData + RecyclerViewData("7", "Seven")
        recyclerViewData = recyclerViewData + RecyclerViewData("8", "Eight")
        recyclerViewData = recyclerViewData + RecyclerViewData("9", "Nine")
        recyclerViewData = recyclerViewData + RecyclerViewData("10", "Ten")
        recyclerViewData = recyclerViewData + RecyclerViewData("11", "Eleven")
        recyclerViewData = recyclerViewData + RecyclerViewData("12", "Twelve")
        recyclerViewData = recyclerViewData + RecyclerViewData("13", "Thirteen")
        recyclerViewData = recyclerViewData + RecyclerViewData("14", "Fourteen")
        recyclerViewData = recyclerViewData + RecyclerViewData("15", "Fifteen")
  
        // create a vertical layout manager
        val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
  
        // create instance of MyRecyclerViewAdapter
        val myRecyclerViewAdapter = MyRecyclerViewAdapter(recyclerViewData)
  
        // attach the adapter to the recycler view
        recyclerView.adapter = myRecyclerViewAdapter
  
        // also attach the layout manager
        recyclerView.layoutManager = layoutManager
  
        // call the method addItemDecoration with the 
        // recyclerView instance and add default Item Divider
        recyclerView.addItemDecoration(
            DividerItemDecoration(
                baseContext,
                layoutManager.orientation
            )
        )
  
        // make the adapter the data set
        // changed for the recycler view
        myRecyclerViewAdapter.notifyDataSetChanged()
    }
}


Output:

Now creating custom divider for RecyclerView items

If the divider needs to be custom then there is a need to create our own shape in the drawable folder. So here the shape is a rectangle with the height of 2dp and the color, green. To implement the same shape invoke the following code inside the divider.xml file and create this file inside the drawable folder.

XML




<?xml version="1.0" encoding="utf-8"?>
    android:shape="rectangle">
    <size android:height="2dp" />
    <solid android:color="@color/green_500" />
</shape>


Now we need to create our own ItemDecoration class and override the onDraw() method. This method is called once and this method decides where the divider needs to be drawn and how to be drawn. One main important thing here is to do not add the divider for the first and last items. To implement the same invoke the following code inside the RecyclerViewItemDecoration.kt file(comments are added for better understanding).

Kotlin




import android.content.Context
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
  
class RecyclerViewItemDecoration(
    context: Context,
    resId: Int
) : RecyclerView.ItemDecoration() {
  
    private var mDivider: Drawable = ContextCompat.getDrawable(context, resId)!!
  
    override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
        super.onDraw(c, parent, state)
  
        // left margin for the divider
        val dividerLeft: Int = 32
  
        // right margin for the divider with
        // reference to the parent width
        val dividerRight: Int = parent.width - 32
  
        // this loop creates the top and bottom 
        // divider for each items in the RV
        // as each items are different
        for (i in 0 until parent.childCount) {
  
            // this condition is because the last 
            // and the first items in the RV have
            // no dividers in the list
            if (i != parent.childCount - 1) {
                val child: View = parent.getChildAt(i)
  
                val params = child.layoutParams as RecyclerView.LayoutParams
  
                // calculating the distance of the
                // divider to be drawn from the top
                val dividerTop: Int = child.bottom + params.bottomMargin
                val dividerBottom: Int = dividerTop + mDivider.intrinsicHeight
  
                mDivider.setBounds(dividerLeft, dividerTop, dividerRight, dividerBottom)
                mDivider.draw(c)
            }
        }
    }
}


Now, this custom ItemDecoration needs to be attached to the recycler view. So now working with the MainActivity.kt file, where we need to pass the instance of custom ItemDecoration class(in this case RecyclerViewItemDecoration). To implement the same invoke the following code inside the MainActivity.kt file.

Kotlin




import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
  
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // create instance of RecyclerView and register with the appropriate ID
        val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
  
        // create list of RecyclerViewData
        var recyclerViewData = listOf<RecyclerViewData>()
        recyclerViewData = recyclerViewData + RecyclerViewData("1", "One")
        recyclerViewData = recyclerViewData + RecyclerViewData("2", "Two")
        recyclerViewData = recyclerViewData + RecyclerViewData("3", "Three")
        recyclerViewData = recyclerViewData + RecyclerViewData("4", "Four")
        recyclerViewData = recyclerViewData + RecyclerViewData("5", "Five")
        recyclerViewData = recyclerViewData + RecyclerViewData("6", "Six")
        recyclerViewData = recyclerViewData + RecyclerViewData("7", "Seven")
        recyclerViewData = recyclerViewData + RecyclerViewData("8", "Eight")
        recyclerViewData = recyclerViewData + RecyclerViewData("9", "Nine")
        recyclerViewData = recyclerViewData + RecyclerViewData("10", "Ten")
        recyclerViewData = recyclerViewData + RecyclerViewData("11", "Eleven")
        recyclerViewData = recyclerViewData + RecyclerViewData("12", "Twelve")
        recyclerViewData = recyclerViewData + RecyclerViewData("13", "Thirteen")
        recyclerViewData = recyclerViewData + RecyclerViewData("14", "Fourteen")
        recyclerViewData = recyclerViewData + RecyclerViewData("15", "Fifteen")
  
        // create a vertical layout manager
        val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
  
        // create instance of MyRecyclerViewAdapter
        val myRecyclerViewAdapter = MyRecyclerViewAdapter(recyclerViewData)
  
        // attach the adapter to the recycler view
        recyclerView.adapter = myRecyclerViewAdapter
  
        // also attach the layout manager
        recyclerView.layoutManager = layoutManager
  
        // call the method addItemDecoration with the 
        // recyclerView instance and pass custom ItemDecoration instance
        recyclerView.addItemDecoration(RecyclerViewItemDecoration(this, R.drawable.divider))
  
        // make the adapter the data set changed
        // for the recycler view
        myRecyclerViewAdapter.notifyDataSetChanged()
    }
}


Output:



Last Updated : 27 Sep, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads