Recycler View for beginners in Android

Abhishek Pathak
5 min readNov 22, 2022

--

What is RecyclerView?

Recyclerview is part of of Android jetpack. It is a UI component that allows the development to create a scrolling list. It is a ViewGroup used to render the data set with the help of adapter and viewholder. It has various view options like linear, grid and straggerd grid using Viewholder pattern.

Major component of RecyclerView :

  • RecylerView.Adapter : It provide recylerview to bind the data set to each item view.
  • Recyclerview.ViewHolder : It is mandatory to apply over recyclerview to draw the UI for each individual item into list.
  • RecyclerView.LayoutManager: You have many options for view managing into recyclerview like
  1. For linear data set/ linear view -> Go for LinearLayout Manager
  2. For Glid data set / grid view -> Go for GlidLayout Manager
  3. For Custom layout view/ Staggered -> Go for StraggerGlidLayoutManager
  • RecyclerView.ItemDecorator : To decorate each of your view, you can customise your item/ divider etc.
  • RecylerView.ItemAnimator : RecyclerView comes up with default animation fetures like when you add new data or delete a item, it will show a very decent animation.

Internal working of RecyclerView

Let’s understand the mechanism of how the process of recyclerview works with data set and new view using scrolling up or down.

  • ViewPort: All visible view item on the screen of recyclerview is part of Android ViewPort. It varies when screen sized increases or decrease like in the above example viewport size is 3.
  • Scrap View: The immediate view item of recyclerview that just gone away either from top / bottom of screen. Also the view that is just moved from view port. This view is not longer going to display and moving into mechanism to recycle the view with new data.
  • Recycle View: After getting view into scrap stage it is going to recycler for further new data.
  • Dirty View: Your old view is recycled and ready to attach with new data.
  • Binding View: New data is will set over the recycled item view and going to visible into recyclerview.
  • Visible View: Visible views are part of android viewport. it may going to scrap view or it may just came from binding with new data form recylerview.

RecyclerView Methods of RecyclerView.Adapter

  • onCreateViewHolder()
  • onBindViewHolder()
  • getItemCount()

Implementation of Recyclerview-

Step 1: Implement xml for item view of recyclerview adapter

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_margin="@dimen/small_padding"
app:cardBackgroundColor="#E3DEDE"
app:cardCornerRadius="@dimen/small_padding"
app:cardElevation="@dimen/small_padding">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/small_padding">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/person_profile"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_baseline_person_pin_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/txt_sender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:gravity="start"
android:textColor="@color/black"
android:textSize="@dimen/medium_text_size"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end"
android:maxLength="15"
app:layout_constraintStart_toEndOf="@+id/guideline"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/sender" />
<TextView
android:id="@+id/txt_subject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:gravity="center"
android:maxLength="25"
android:textColor="#505050"
android:textSize="@dimen/small_text_size"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/txt_sender"
tools:text="@string/global_warming" />
<TextView
android:id="@+id/txt_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:maxLength="25"
android:maxLines="1"
android:textColor="#505050"
android:textSize="@dimen/body_text_size"
app:layout_constraintStart_toEndOf="@+id/guideline"
app:layout_constraintTop_toBottomOf="@+id/txt_subject"
tools:text="@string/global_warming" />
<TextView
android:id="@+id/txt_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:ellipsize="end"
android:gravity="center"
android:maxLength="10"
android:textColor="#0040FF"
android:textSize="@dimen/body_text_size"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@+id/guideline2"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/time" />
<ToggleButton
android:id="@+id/img_favourite"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="@dimen/small_padding"
android:background="@drawable/toggle_selector"
app:layout_constraintEnd_toEndOf="parent"
android:textOn=""
android:textOff=""
app:layout_constraintTop_toBottomOf="@+id/txt_time" />

<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.2" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.80" />
</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

Step 2: Implement data class for View

data class MailDetails(
val sender: String,
val title: String,
val body: String,
val time: String,
val isFavourite: Boolean
) : Serializable

Step 3: Implement Adapter of recyclerview

data class MailDetails(
val sender: String,
val title: String,
val body: String,
val time: String,
val isFavourite: Boolean
) : Serializable
class MailAdapter(private val context: Context, private val mailDetails: List<MailDetails>) :
RecyclerView.Adapter<MailAdapter.MailViewHolder>() {

private lateinit var binding: ItemViewBinding
/*
This method needs to override to define the size of recycler view*/
override fun getItemCount() = mailDetails.size
/*
This method will call only once when you create adapter for recycler view.
Responsibility of this method is to create new views.*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MailViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
binding = ItemViewBinding.inflate(layoutInflater, parent, false)
return MailViewHolder(binding.root)
}
/*
This method will call any number of times when you scroll up or down the list
Responsibility of this method is to bind the new data with position of list*/
override fun onBindViewHolder(holder: MailViewHolder, position: Int) {
holder.apply {
txtSender.text = mailDetails[position].sender
txtSubject.text = mailDetails[position].title
txtBody.text = mailDetails[position].body
txtTime.text = mailDetails[position].time
itemView.setOnClickListener {
val intent = Intent(context, DetailActivity::class.java)
intent.putExtra(MAIL_DATA, mailDetails[position] as Serializable)
context.startActivity(intent)
}
}
}
inner class MailViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val txtSender: TextView = binding.txtSender
val txtSubject: TextView = binding.txtSubject
val txtBody: TextView = binding.txtBody
val txtTime: TextView = binding.txtTime
}
companion object{
const val MAIL_DATA = "mail data"
}
}

Step 4: Implement the view for activity

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_View_fruits"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F2F2F2" />
</androidx.constraintlayout.widget.ConstraintLayout>

Step 5: Implement RecyclerView in Activity

class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var mailAdapter: MailAdapter
private val mailList = ArrayList<MailDetails>()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
makeData()
}
private fun makeData(){
mailList.apply {
add(MailDetails("Facebook","Pocked new user","You have new friends suggestions","12:22 AM",false))
add(MailDetails("Amazon","Avengers","You have new friends suggestions? how about you","12:22 AM",true))
add(MailDetails("Google","Rock","You have new friends suggestions","1:22 AM",false))
add(MailDetails("Patrick@appolis.com","Android discussion call at 8 AM morning","Hey patrick, \n Good day!! \n Hope you are doing well!!, Mountains are degrading,please do needful work here in this app hey how are your i am working with you a log You have new friends suggestions, hey i am happy to work with you, \n\n\n Regards, \n Abhishek Pathak \n Android Lead ","1:22 AM",false))
add(MailDetails("Jack","please do needful work here in this app","You have new friends suggestions","12:22 AM",true))
add(MailDetails("Bob","look like app is working fine to me","You have new friends suggestions","12:33 AM",false))
add(MailDetails("Uncle","Pocked new user","You have new friends suggestions","12:42 AM",true))
add(MailDetails("Hero","What you are working here in this country","You have new friends suggestions for an user of an list of data","12:22 AM",false))
}
mailAdapter = MailAdapter(this, mailList)
binding.apply {
recyclerViewFruits.layoutManager = LinearLayoutManager(this@MainActivity)
recyclerViewFruits.adapter = mailAdapter
}
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.adapterPosition
mailList.removeAt(position)
mailAdapter.notifyItemRemoved(position)
Toast.makeText(this@MainActivity, "Item deleted", Toast.LENGTH_SHORT).show()
}
}).attachToRecyclerView(binding.recyclerViewFruits)
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position = viewHolder.adapterPosition
mailList.removeAt(position)
mailAdapter.notifyItemRemoved(position)
Toast.makeText(this@MainActivity, "Item Archived", Toast.LENGTH_SHORT).show()
}
}).attachToRecyclerView(binding.recyclerViewFruits)
}
}

Result is below:

Next Steps

Thanks for reading this article. Be sure to click 👏 below to applause this article if you found it helpful. It means a lot to me.

--

--