DiffUtils vs stable Ids in recycler view

Viewed 2687

I have been reading a lot about the optimisations in RecyclerView for quite some time and have learnt a lot of new concepts. One thing that isn't still clear is that can we use both stable ids and DiffUtils together in a RecyclerView. Are there possible benefits/drawbacks of this approach? From what I have read, I think using DiffUtils alone will give all the possible benefits of the reuse of viewHolders and nice animations(correct me if I am wrong). A detailed comparison would be really helpful.

3 Answers

Long story short, DiffUtill fully replaces stableIds approach.

StableIds is a legacy approach from the times when everybody was migrating from ListView to RecyclerView. Along with ItemAnimator it provided an easy approach to get simple predictive animations out of the box. Predictive meaning that RV could deduce itself which items are added/removed or moved when you just called notifyDataSetChanges without bothering about other callbacks.

Once DiffUtil came along there were no need to RV to deduce that, cause DiffUtills tells RV exactly which items are being moved/added/removed.

I use RV in very tough conditions with dozens of item types, and multiple data updates per second, and spend dozen hours debugging RV and animations internals and didn't notice any significant changes in its scrapping/de-scrapping/1-2-3-steps-layouting behaviour when was trying to add stableIds on top of DiffUtil.

Here's a big piece on how animations worked in circa 2015 pre DiffUtill:

https://www.birbit.com/recyclerview-animations-part-1-how-animations-work/

https://www.birbit.com/recyclerview-animations-part-2-behind-the-scenes/

And a little bit more if you're interested in RV internals:

https://android.jlelse.eu/anatomy-of-recyclerview-part-1-a-search-for-a-viewholder-404ba3453714

Yes, you can.

If you use androidx.recyclerview.widget.ListAdapter (which you should), you actualy has to provide a DiffUtil. Just look at the constructor. And then nothing is stopping you from providing stable ids.

Actualy, if you don't use stable ids, and submit a new list with event just a minor change, all the items in RecyclerView will "flash". But if you use stable ids, the change will animate nicely.

Also know, that they have no dependency on each other, you'll just probably use the same id (or whatever) field from your items in both getItemId() and DiffUtil.

As per docs DiffUtils:

DiffUtil is a utility class that can calculate the difference between two lists and output a list of update operations that converts the first list into the second one.

It can be used to calculate updates for a RecyclerView Adapter. See ListAdapter and AsyncListDiffer which can compute diffs using DiffUtil on a background thread.

DiffUtil uses Eugene W. Myers's difference algorithm to calculate the minimal number of updates to convert one list into another. Myers's algorithm does not handle items that are moved so DiffUtil runs a second pass on the result to detect items that were moved.

and as per this Answer StableIds is

Stable IDs allow the ListView to optimize for the case when items remain the same between notifyDataSetChanged calls. The IDs it refers to are the ones returned from getItemId.

Without it, the ListView has to recreate all Views since it can't know if the item IDs are the same between data changes (e.g. if the ID is just the index in the data, it has to recreate everything). With it, it can refrain from recreating Views that kept their item IDs.

Hope you concept will clear now.

Related