The powerfull Diff Util in Android Recycler View

Related tags

Adapter DiffUtil
Overview

DiffUtil

The powerfull Diff Util in Android Recycler View

What is RecyclerView ?

RecyclerView is flexible and efficient version of ListView. It is an container for rendering larger data set of views that can be recycled and scrolled very efficiently.

Before discussing about DiffUtil lets have a look at the code using Recycler View

Student.kt


data class Student(
    val name: String,
    val id: Int,
    val age: Int,
    val address: String
)

StudentAdapter.kt

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_layout.view.*

class StudentAdapter :
    RecyclerView.Adapter<StudentAdapter.StudentViewHolder>() {

    private val studentList: ArrayList<Student> = ArrayList<Student>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StudentViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
        return StudentViewHolder(view)
    }

    override fun onBindViewHolder(viewholder: StudentViewHolder, position: Int) {
        val student = studentList[position]
        viewholder.setData(student)
    }

    override fun getItemCount(): Int {
        return studentList.size
    }

    fun updateData(newStudentList: List<Student>) {
        studentList.clear() 
        studentList.addAll(newStudentList)
    }


    class StudentViewHolder(private val itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun setData(student: Student) {
            itemView.apply {
                tvName.text = student.name
                tvAge.text = "${student.age}"
                tvAddress.text = student.address
            }
        }
    }

}

MainActivity.kt

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    private var studentList = ArrayList<Student>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        buildData()
        setAdapter()
    }

    private fun buildData() {
        for (i in 1..100) {
            val student = Student("Lloyd-$i", i, 26, "Jayanagar 4th Block-$i Bangalore")
            studentList.add(student)
        }
    }

    private fun setAdapter() {
        val linearLayoutManager = LinearLayoutManager(this)
        val studentAdapter = StudentAdapter()
        recyclerView.apply {
            adapter = studentAdapter
            layoutManager = linearLayoutManager
            studentAdapter.updateData(studentList)
        }

    }
}

Now imagine the data set has changed and you want to notify the Adapter about the changes then we call

studentAdapter.updateData(studentList)

and

studentAdapter.notifyDataSetChanged();

This will update the recycler view with new set of Data.

But if notifyDataSetChanged was doing the work for you, why was DiffUtils was need?

Let's discuss that now,

  • Using notifyDataSetChanged() , there is no way for the RecyclerView to know what the actual changes are there. So, all the visible views are recreated again. This is a very expensive operation. In this process, the new instance is created of the adapter. Which makes the process very heavy.
  • To over come this, Android Launched DiffUtils as part of support library.

DiffUtils is used to know the updats made in the RecyclerView Adapter.

DiffUtil uses these methods to notify the RecyclerView for any changes in the data set:

  • notifyItemMoved
  • notifyItemRangeChanged
  • notifyItemRangeInserted
  • notifyItemRangeRemoved

Compared to notifyDataSetChanged() , these methods are far more efficient.

DiffUtilCallBack.kt

import androidx.recyclerview.widget.DiffUtil

class DiffUtilCallBack(
    private val oldStudentsList: List<Student>,
    private val newStudentList: List<Student>
) : DiffUtil.Callback() {

    override fun getOldListSize(): Int {
        return oldStudentsList.size
    }

    override fun getNewListSize(): Int {
        return newStudentList.size
    }

    /**
     * Checks if the items are same based on a key value i.e here considering id is unique
     */
    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return oldStudentsList[oldItemPosition].id == newStudentList[newItemPosition].id
    }

    /**
     * This is called if the areItemsTheSame returns true and checks if other contents are the same
     */
    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
        return oldStudentsList[oldItemPosition] == newStudentList[newItemPosition]
    }
    
    /**
    * If areItemTheSame return true and areContentsTheSame returns false DiffUtil calls this method to get a payload about the change.
    */
    override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
        return super.getChangePayload(oldItemPosition, newItemPosition)
    }
}
  • getOldListSize() : It returns the size of the old list.

  • getNewListSize() : Returns the size of the new list

  • areItemsTheSame( oldPosition:Int , newPosition:Int) : Called by the DiffUtil to decide whether two object represent the same Item in the old and new list.

  • areContentsTheSame( oldPosition:Int, newPosition:Int) : Checks whether two items have the same data.You can change its behavior depending on your UI. This method is called by DiffUtil only if areItemsTheSame returns true. In our example, we are comparing the name and value for the specific item

  • getChangePayload(oldPosition:Int , newPosition:Int) : If areItemTheSame return true and areContentsTheSame returns false DiffUtil calls this method to get a payload about the change.

  • getChangePayload(oldPosition:Int , newPosition:Int) : If areItemTheSame return true and areContentsTheSame returns false DiffUtil calls this method to get a payload about the change.

Now make the below changes to the StudentAdapter

    fun updateData(newStudentList: List<Student>) {
        val diffUtilCallBack = DiffUtilCallBack(studentList, newStudentList)
        val diffResult = DiffUtil.calculateDiff(diffUtilCallBack)
        studentList.clear() // clear the old student list
        studentList.addAll(newStudentList) // update the old list with new List
        diffResult.dispatchUpdatesTo(this)
    }

So here we are passing the oldStudentList and newStudentList to the DiffUtilCallback class and calculating the difference between the 2 lists.

After we know the difference, we update the studentList and notify the adapter via dispatchUpdatesTo .

You might also like...
Simplify Adapter creation for your Android ListViews.

FunDapter takes the pain and hassle out of creating a new Adapter class for each ListView you have in your Android app. It is a new approach to custom

This library provides GridAdapters(ListGridAdapter & CursorGridAdapter) which enable you to bind your data in grid card fashion within android.widget.ListView, Also provides many other features related to GridListView.
This library provides GridAdapters(ListGridAdapter & CursorGridAdapter) which enable you to bind your data in grid card fashion within android.widget.ListView, Also provides many other features related to GridListView.

GridListViewAdapters This libarary enables you to implement GridView like card layout within ListView with added capabilites like Paginations, Additio

Just like instant coffee, saves 78% of your time on Android's Custom Adapters.

Notice Instant Adapter is now part of an even more awesome Adapter Kit project! Instant Adapter Just like instant coffee, saves 78%* of your time on A

This library provides Easy Android ListView Adapters(EasyListAdapter & EasyCursorAdapter) which makes designing Multi-Row-Type ListView very simple & cleaner, It also provides many useful features for ListView.
This library provides Easy Android ListView Adapters(EasyListAdapter & EasyCursorAdapter) which makes designing Multi-Row-Type ListView very simple & cleaner, It also provides many useful features for ListView.

EasyListViewAdapters Whenever you want to display custom items in listview, then only way to achieve this is to implement your own subclass of BaseAda

An android open-source quick search/diff/download plugin.
An android open-source quick search/diff/download plugin.

Android Reference Intellij Plugin This library based on AndroidSourceViewer It's built with the Gradle and rewritten by kotlin, that's why it's a new

Multiplaform kotlin library for calculating text differences. Based on java-diff-utils, supports JVM, JS and native targets.

kotlin-multiplatform-diff This is a port of java-diff-utils to kotlin with multiplatform support. All credit for the implementation goes to original a

An intelligent diff tool for the output of Gradle's dependencies task

Dependency Tree Diff An intelligent diff tool for the output of Gradle's dependencies task which always shows the path to the root dependency. +--- c

Generate data-view-binding adapters of android recycler view.

Items 这个库可以为 Android 的 RecyclerView 生成基于 Data-View-Binding 的 Adapter。 对比其他一些类似的开源库,它有以下的一些优势: 更好的拓展性。这个库不需要你继承特定的 Adapter 或 ViewHolder 类,你可以继承任何第三方提供的

Handy library to integrate pagination, which allow no data layout, refresh layout, recycler view in one view and easy way to bind pagination in app.
Handy library to integrate pagination, which allow no data layout, refresh layout, recycler view in one view and easy way to bind pagination in app.

Pagination View Handy library to integrate pagination, which allow no data layout, refresh layout, recycler view in one view and easy way to bind pagi

A util for setting status bar style on Android App.
A util for setting status bar style on Android App.

StatusBarUtil A util for setting status bar style on Android App. It can work above API 19(KitKat 4.4). 中文版点我 Sample Download StatusBarUtil-Demo Chang

A util for setting status bar style on Android App.
A util for setting status bar style on Android App.

StatusBarUtil A util for setting status bar style on Android App. It can work above API 19(KitKat 4.4). 中文版点我 Sample Download StatusBarUtil-Demo Chang

 Slack Webhook Util For Android
Slack Webhook Util For Android

Slack Webhook Util For Android • About • Setup • How to use • License About "Slack Webhook Util" 은 안드로이드에서 Webhook을 쉽게 보내기 위한 라이브러리 입니다. Builder 패턴으로

This is a simple util to create Activity transition animation
This is a simple util to create Activity transition animation

TransitionHelper This is a simple util to create Activity transition animation API compatible with Android 2.2+ 中文说明 Screenshots How to use 1.startAct

A couple of sticky header decorations for android's recycler view.
A couple of sticky header decorations for android's recycler view.

DEPRECATION NOTICE This library has not been touched in a very long time and many things have changed in the android ecosystem since then. Updating an

A couple of sticky header decorations for android's recycler view.
A couple of sticky header decorations for android's recycler view.

DEPRECATION NOTICE This library has not been touched in a very long time and many things have changed in the android ecosystem since then. Updating an

Small, smart and generic adapter for recycler view with easy and advanced data to ViewHolder binding.
Small, smart and generic adapter for recycler view with easy and advanced data to ViewHolder binding.

smart-recycler-adapter Never code any boilerplate RecyclerAdapter again! This library will make it easy and painless to map your data item with a targ

Custom Layout Manager for Recycler View
Custom Layout Manager for Recycler View

Circular Layout Manager Overview A library for Android which essentially contains a Custom Layout Manager for Recycler View which lays out its child v

A custom recycler view with shimmer views to indicate that views are loading.
A custom recycler view with shimmer views to indicate that views are loading.

ShimmerRecyclerView Intro A custom recycler view with shimmer views to indicate that views are loading. The recycler view has a built-in adapter to co

Medium sample for frogo-recycler-view

mediumstory-frogo-recycler-view Tutorial how to use frogo-recycler-view lib Medium sample for frogo-recycler-view Medium Story Here frogo-recycler-vie

Owner
Lloyd Dcosta
Lloyd Dcosta
Small, smart and generic adapter for recycler view with easy and advanced data to ViewHolder binding.

smart-recycler-adapter Never code any boilerplate RecyclerAdapter again! This library will make it easy and painless to map your data item with a targ

Manne Öhlund 405 Dec 30, 2022
Android library for the adapter view (RecyclerView, ViewPager, ViewPager2)

Antonio Android library for the adapter view (RecyclerView, ViewPager, ViewPager2) Free from implementation of the adapter's boilerplate code ! Reuse

NAVER Z 106 Dec 23, 2022
Vector map library and writer - running on Android and Desktop.

Mapsforge See the integration guide and changelog. And read through how to contribute guidelines. If you have any questions or problems, don't hesitat

mapsforge 1k Jan 2, 2023
Epoxy is an Android library for building complex screens in a RecyclerView

Epoxy Epoxy is an Android library for building complex screens in a RecyclerView. Models are automatically generated from custom views or databinding

Airbnb 8.1k Jan 4, 2023
Renderers is an Android library created to avoid all the boilerplate needed to use a RecyclerView/ListView with adapters.

Renderers Renderers is an Android library created to avoid all the RecyclerView/Adapter boilerplate needed to create a list/grid of data in your app a

Pedro Vicente Gómez Sánchez 1.2k Nov 19, 2022
Android - A ListView adapter with support for multiple choice modal selection

MultiChoiceAdapter MultiChoiceAdapter is an implementation of ListAdapter which adds support for modal multiple choice selection as in the native Gmai

Manuel Peinado Gallego 855 Nov 11, 2022
Android library to auto-play/pause videos from url in recyclerview.

AutoplayVideos Show some ❤️ and star the repo to support the project This library is created with the purpose to implement recyclerview with videos ea

Krupen Ghetiya 989 Nov 17, 2022
:page_with_curl: [Android Library] Giving powers to RecyclerView

Android library that provides most common functions around recycler-view like Swipe to dismiss, Drag and Drop, Divider in the ui, events for when item

Nishant Srivastava 644 Nov 20, 2022
[] Easy Adapters library for Android

Deprecated Due to the growing use of the RecyclerView and the RecyclerView.Adapter provided adapter class, Easy-Adapter is now deprecated. Whilst the

ribot 425 Nov 25, 2022
Adapter Kit is a set of useful adapters for Android.

Adapter Kit Adapter Kit is a set of useful adapters for Android. The kit currently includes, Instant Adapter Instant Cursor Adapter Simple Section Ada

Ragunath Jawahar 368 Nov 25, 2022