How to Add Dividers in Android RecyclerView?
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.
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 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 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:
Please Login to comment...