In my RecyclerView, I used ListAdapter combined with DiffUtil.ItemCallback.
class CustomDiffCallback : DiffUtil.ItemCallback<TypeInterface>() {
override fun areItemsTheSame(p0: TypeInterface, p1: TypeInterface): Boolean {
return ((p0 is Type1 && p1 is Type1) && p0.id == p1.id)
|| (p0 is Type2 && p1 is Type2)
|| (p0 is Type3 && p1 is Type3)
}
override fun areContentsTheSame(p0: TypeInterface, p1: TypeInterface): Boolean {
return ((p0 is Type1 && p1 is Type1) && p0 == p1)
|| (p0 is Type2 && p1 is Type2)
|| (p0 is Type3 && p1 is Type3)
}
}
The RecyclerView items have 3 different types all inheriting from same interface.
Strange thing is, when I inserted an item into the second last position of the list, instead of showing the last item, it duplicates the last item twice.
Ex) oldlist = A B C D, newlist = A B C X D
the list appears as A B C D D
I used debugger to investigate into what is going on in the computation process, and found that the computation was performed in the following order:
areContentsTheSame(oldlist[4], newlist[5])
areContentsTheSame(oldlist[0], newlist[0])
areContentsTheSame(oldlist[1], newlist[0])
areContentsTheSame(oldlist[2], newlist[2])
areContentsTheSame(oldlist[3], newlist[3])
Leaving out newlist[4], which is the newly inserted element.
Is this natural blind spot embedded in DiffUtil.ItemCallback or am I using the ItemCallback in a wrong way?
newlist[0]matches botholdlist[0]andoldlist[1]. Or you're mutating the lists instead of serving new instances (diffutil hates that)