Lists with DiffUtil and ListAdapter

September 28, 2021 Publish By : EXPERT APP DEVS 4 min read Viewed By : 604
Lists with DiffUtil and ListAdapter

Writing code to show lists of records is an ordinary venture as a developer, regardless of platform. Operations to adjust lists can range in complexity, and force developers down paths that sacrifice user experience or performance. This article will display you how to leverage DiffUtil and ListAdapter to keep away from the ones pitfalls, and offer a more efficient user experience, whilst decreasing boilerplate code.

If you're an Android app developer, chances are you'll have implemented recyclerview. A Recyclerview is used to show a listing of information. It may be such things as a listing of issues, a to-do listing, a film listing, etc. Most of the time we turn out to be the usage of notifyDataSetChanged() to inform information updates.

Implement Recyclerview with adapter

So we could get started and see how we are able to implement Recyclerview with Adapter.

No extra dependency is needed, we simply want to add recyclerview.

implementation "androidx.recyclerview:recyclerview:1.1.0"

Create a data class :

data class PostInfo(val id:Int, val title:String, val body:String)

Create a adapter class :

we just  extend ListAdapter class and implement constructor with a class extending DiffUtil.ItemCallback as a parameter which does the data replace calculation for us, that's a chunk one of a kind while in comparison with the present RecyclerView Adapter.

We just extend the ListAdapter class and pass TaskDiffCallBack and TaskDiffCallBack extends DiffUtilItemCallback. 

class PostInfoAdapter :ListAdapter<PostInfo, PostListAdapter.ViewHolder>(TaskDiffCallBack()) {
    class TaskDiffCallBack : DiffUtil.ItemCallback<Post>() {
        override fun areItemsTheSame(oldItem: PostInfo, newItem: PostInfo): Boolean {          
            return oldItem.id == newItem.id;
        }
        override fun areContentsTheSame(oldItem: PostInfo, newItem: PostInfo): Boolean {        
            return oldItem == newItem
        }
    }
}

 

Understand diffUtils methods :

areItemsTheSame(T old, T new)

Called to test whether or not items represent the same item. If your items have specific ids, this approach should take a look at their id equality. Here we take a look at as PostInfo is specific we've taken a look at on id, it can wear any specific constraint for your model.

areContentsTheSame(T old, T new)

items have the identical data. This approach is referred to as only if areItemsTheSame(T, T) returns true for those items, i.e. if any of the id is to be had in each new and old listing it might compare actual properties to affirm in the event that they have modified and with Kotlin all we want to do is old == new.

​​Accessing Data in onBindViewHolder

override fun onBindViewHolder(holder: ViewHolder, position: Int) { 
        val object = getItem(position)
        holder.tvDescStr.text = object.body
        holder.tvTitleStr.text = object.title }

 

Call Adapter class in Activity 

Now we have to initialize our Adapter class  and set our recyclerview adapter to Adapter object, and call our updatePostInfoAdapter with the desired parameter. At last, we simply want to name the adapter.submitList(postDataList). So subsequent time we've got if we've got new data we'd simply name the identical function with up to date and Our DiffUtil Implementation might take care of calculating the modifications in the new List and communicate it to our PostInfoAdapter.

class MainActivity : AppCompatActivity() {
    lateinit var adapter: PostInfoAdapter
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)  
        val postDataList = getListOfPost(20)
        adapter = PostInfoAdapter()
        rvPostList.adapter = adapter
        updatePostInfoAdapter(postDataList)

        btnRefresh.setOnClickListener {  
            val updatedPostInfoList = getListOfPosts(20)
            updatePostInfoAdapter(updatedPostList)
        }
    }
    fun updatePostInfoAdapter(postList: List<PostInfo>) {
        //important method which does the work of updating the items in Adapter
        adapter.submitList(postDataList)
    }
}


Final Statement

  • No need Of notifyDataSetChanged method: submitList looks after changing the existing listing of records with new and notify the identical to the adapter.
  • Internally it calls DiffUtil.calculateDiff which does the managing for us
  • All this calculation takes place off the main thread
  • For the primary run, nothing occurs; it simply shows the listing at once with no check.

Need a consultation?

Drop us a line! We are here to answer your questions 24/7.