Step #4: Comparing Our Models
The constructor parameter that we are missing to the ListAdapter
constructor is an instance of the awkwardly-named DiffUtil.ItemCallback
interface. This interface tells ListAdapter
how to compare two model objects. In particular, it tells ListAdapter
whether two model objects should be visually identical, so RecyclerView
does not have to re-draw or move around views that have not changed their appearance. So, we need an object that can do this for us to provide to ListAdapter
.
We can take advantage of a couple of Kotlin features as part of this work:
- A Kotlin source file is not limited to a single class, the way Java source files are
- Kotlin has an
object
keyword for creating single instances of objects, for places where we only need one
With that in mind, at the bottom of the RosterAdapter
Kotlin file, add this:
private object DiffCallback : DiffUtil.ItemCallback<ToDoModel>() {
override fun areItemsTheSame(oldItem: ToDoModel, newItem: ToDoModel) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: ToDoModel, newItem: ToDoModel) =
oldItem.isCompleted == newItem.isCompleted &&
oldItem.description == newItem.description
}
This implements DiffUtil.ItemCallback
for ToDoModel
. areItemsTheSame()
needs to return true
if the two models are really the same thing — in our case, that would be determined using their unique IDs. areContentsTheSame()
should return true
if the two models’ visual representations are the same. Our CheckBox
will use the description
property for the text and the isCompleted
property for the checked state, so areContentsTheSame()
compares those two values. In particular, the notes
property is ignored for this comparison, since it will not appear in the list rows.
Then, add DiffCallback
as the missing constructor parameter to ListAdapter
. This means the entire Kotlin source file at this point should look like:
package com.commonsware.todo
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
class RosterAdapter : ListAdapter<ToDoModel, RosterRowHolder>(DiffCallback) {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): RosterRowHolder {
TODO("Not yet implemented")
}
override fun onBindViewHolder(holder: RosterRowHolder, position: Int) {
TODO("Not yet implemented")
}
}
private object DiffCallback : DiffUtil.ItemCallback<ToDoModel>() {
override fun areItemsTheSame(oldItem: ToDoModel, newItem: ToDoModel) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: ToDoModel, newItem: ToDoModel) =
oldItem.isCompleted == newItem.isCompleted &&
oldItem.description == newItem.description
}
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.