In this tutorial, we will learn how to improve RecyclerView performance using DiffUtil in android recyclerView with a step-by-step explanation. if you don’t know what is RecyclerView in android then you can go through it Android RecyclerView in Kotlin with Example.
In the real world, Android RecyclerViews displaying some kind of list are present in almost every Android application. Lists contain a lot of information, so it’s critical to provide a smooth experience when a user scrolls through one and when its content is updated. DiffUtil is a utility class that was created to assist with this, and Android RecyclerView uses DiffUtil to provide this feature.
Output:
Contents
What is DiffUtil?
DiffUtil is a utility class that computes the difference between two lists and returns a list of update operations that transforms the first list into the second.
It is capable of calculating updates for a RecyclerView Adapter. See ListAdapter and AsyncListDiffer for help with using DiffUtil on a background thread.
DiffUtil employs Eugene W. Myers’ difference algorithm to determine the smallest number of updates required to convert one list to another. Because Myers’ algorithm does not handle items that have been moved, DiffUtil performs a second pass on the result to detect items that have been moved.
If the lists are large, this operation may take significant time so you are advised to run this on a background thread, get the DiffUtil.DiffResult then applies it on the RecyclerView on the main thread.
Why do we use DiffUtil in recyclerView?
- DiffUtil is a utility class that computes the difference between two lists and returns a list of update operations that converts the first list to the second. It is capable of calculating updates for a RecyclerView Adapter.
- Most of the time, our list completely changes, and we set a new list to RecyclerView Adapter. To update the adapter, we use notifyDataSetChanged. NotifyDataSetChanged is an expensive operation. The DiffUtil class now handles that issue. It does an excellent job!
DiffUtil callback Methods
- getOldListSize(): This function returns the length of the old list.
- getNewListSize() : Returns the new list’s size.
- areItemsTheSame(int oldItemPosition, int newItemPosition) : The DiffUtil calls this method to determine whether two objects represent the same Item.If your items have unique identifiers, this method should validate their ids.
- Checks whether two items have the same data areContentsTheSame(int oldItemPosition, int newItemPosition) :Depending on your UI, you can modify its behaviour. DiffUtil calls this method only if areItemsTheSame returns true.
What is List Adapter?
ListAdapter is a wrapper around the AyncListDiffer helper. It includes computing diffs between Lists on a background thread and handling updates at different adapter positions. All you need to do is make a call to the submitList(data: List) function and it will compute the best way to update the items for you.
Using DiffUtil in Android RecyclerView Example
Step by Step explanation
Step 1: Add recyclerView in activity_main.xml file as shown in below code:
<?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=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Step 2: Create a new layout resources file for recyclerView, name it item_view, and add the code given below:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/First" android:layout_width="45dp" android:gravity="center" android:textColor="@color/black" android:textSize="24sp" android:background="@color/teal_200" android:layout_height="45dp" android:text="K" /> <TextView android:id="@+id/name" android:layout_weight="1" android:text="Kotlin" android:fontFamily="sans-serif-black" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
Step 3: Create a data class, name it ListItem and add the code given below:
package com.sagar.listadapter data class ListItem(val id: Int, val First: String,val name: String)
Step 4: Create an Adapter for recyclerView, name it ListAdapter and add the code given below:
package com.sagar.listadapter import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView class ListAdapter : androidx.recyclerview.widget.ListAdapter<ListItem, ListAdapter.ListViewHolder>(DiffUtil()) { class ListViewHolder(view: View) : RecyclerView.ViewHolder(view) { val name = view.findViewById<TextView>(R.id.name) val First = view.findViewById<TextView>(R.id.First) fun bind(item: ListItem) { name.text = item.name First.text = item.First } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_view, parent, false) return ListViewHolder(view) } override fun onBindViewHolder(holder: ListViewHolder, position: Int) { val item = getItem(position) holder.bind(item) } class DiffUtil : androidx.recyclerview.widget.DiffUtil.ItemCallback<ListItem>() { override fun areItemsTheSame(oldItem: ListItem, newItem: ListItem): Boolean { return oldItem.id == newItem.id } override fun areContentsTheSame(oldItem: ListItem, newItem: ListItem): Boolean { return oldItem == newItem } } }
Step 5: In MainActivity class add the code given below:
package com.sagar.listadapter import android.os.Bundle import android.os.Handler import android.os.Looper 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) val recyclerView = findViewById<RecyclerView>( R.id.recyclerView ) val adapter = ListAdapter() val La = ListItem(1, "K", "Kotlin") val Lb = ListItem(2, "H", "HTML") val Lc = ListItem(3, "J", "JavaScript") adapter.submitList(listOf(La, Lb, Lc)) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.setHasFixedSize(true) recyclerView.adapter = adapter Handler(Looper.getMainLooper()).postDelayed(Runnable { val Lc = ListItem(3, "J", "JavaScript") val Ld = ListItem(4, "W", "Website") val Le = ListItem(5, "R", "Ruby") val Lf = ListItem(6, "C", "C++") val Lg = ListItem(7, "S", "Swift") val Lh = ListItem(8, "F", "Flutter") adapter.submitList(listOf(Lc, Ld, Le, Lf, Lg, Lh)) }, 3000) } }
Source Code:
We’ve completed the development of the DiffUtil using Recycleview with ListAdapter. You can get the Source code from the given below button.
- We hope that this guide will assist you in understanding all about the concepts of DiffUtil using Recycleview with ListAdapter. We have concentrated on making a basic, meaningful and easy-to -learn guide to the concepts of it with suitable example. Still if you have any problems regarding it, please post them in the comments section, we will be glad to assist you.
Pingback: Broadcast Receiver in Android Studio with Example - Developers Dome