google/agera

Fine grained updates for RecyclerView Adapter

LouisCAD opened this issue ยท 9 comments

Hi!

Agera RecyclerView Adapter always calls notifyDataSetChanged(), regardless of what changed, which is bad according to RecyclerView guys (you can ask @yigit or his teammates), and I think so too, as it makes the adapter invalidate everything even if just one item was added.

Fine grained data changes notifications such as notifyItemChanged(int position) or notifyItemRemoved(int position) are better for user experience (can have comprehensible animations following the changed that occurred), and performance.

I'm not an Agera expert yet, but I would like to get advice, or better, a sample on how such an Adapter could work with Agera and if it could be integrated in the rvadapter official Agera extension.

Thanks!

Hi.

Fine-grained events are not available because Repositories themselves don't have fine-grained events. To fire such events, either the RepositoryPresenter (client code) will be responsible for the job -- which makes it very difficult to implement, or RepositoryAdapter needs to magically discover the right sequence of events to notify the RecyclerView, which requires RepositoryPresenters to provide more information; most probably the data items' stable IDs.

However, with one single "the world has changed" event, just the stable IDs can already enable smooth animation in RV. Let all RepositoryPresenters provide stable IDs (implement RepositoryPresenter.getItemId(...)), and then enable stable ID in the RepositoryAdapter. Some predictive animations will be "wrong" (items fading in and out rather than sliding in and out, because RV doesn't know where those newly-on-screen items come from), but items that have not changed will not "flash" (disappear and appear).

@maxtroy Thanks for the stable IDs tip! It would be a good candidate for Agera's rvadapter documentation!

It does not completely solves the little performance hit though (but is good enough to be implemented if Agera use can improve code quality in the use case), so I'll let this issue open, if anyone have a solution to make fine grained RecyclerView Adapter notifications usable with Agera.

I have a better plan for this issue. Stay tuned for Agera 1.5 (or 1.6) :)

@maxtroy You plan to use DiffUtil, right?

It's a solution that enables client code to use DiffUtils easily. Client code doesn't need to actually use DiffUtils.

@LouisCAD please try out the new fine-grained event support and let us know what you think!

@maxtroy How can I test it? Need to clone the repository? Is there an example in the sample?

The sample isn't in the perfect shape to demo the fine-grained events right now. In particular there's no change and move events. It needs a bit of tweaking.

Meanwhile, you can try out by doing one of the following:

  • In your subclass(es) of RepositoryPresenter, override the new getUpdates() method to provide your own fine-grained events.
  • In your compiled RepositoryPresenter (RepositoryPresenters.repositoryPresenterOf(...)), or compiled data-binding RepositoryPresenter, add a .diffWith(...) directive to enable using DiffUtil to compute the fine-grained events.

You can now turn off stable IDs, if you like.

You can get the complete information in the documentation of RepositoryPresenter.getUpdates(), and the compilers' diffWith() and diff() directives.

This is now included in 1.4.0-alpha4