To properly implement a DiffUtil.ItemCallback<T>
passed inside the constructor of ListAdapter, both areItemsTheSame
and areContentsTheSame
must be implemented.
Now for areItemsTheSame
it is advised that a unique identifier of type of . So for my case where is a data class without a deducible unique identifier, how am I supposed to implement it properly? When simply doing oldItem == newItem
in both functions, I obviously get a flashing animation on the item since it thinks it's a completely different item since areItemsTheSame
returned false.
So how do people fix this properly? Would returning true
anyway if the data type is the same which would then trigger the areContentsTheSame
be a fix? And if not, why? If I do that currently, the recycler properly understands that just some data has changed, and only the necessary parts of the view "flash" with the new data.
CodePudding user response:
So how do people fix this properly?
The "solution" is to have a unique identifier for each row (which is good advice for most relational data structures).
You can combine fields in either method, the callback offers you both items (old and new) and you get to decide what to do/compare in there.
When the items "are the same" (as determined by your implementation), then this allows the RecyclerView/Adapter combo to make assumptions (and optimizations).
When the items are determined to have changed (meaning they are now two different items), then a different set of things must happen (animations, rebinding, determining the viewType, etc.). More work for the UI.
So don't fight the framework, instead provide a unique identifier, even if it's composed of more than one field. I'm curious to see your data class to understand how comes there's no unique way to identify a single row.