0

I am using the Paging library from Android Jetpack to have a paged loading behavior in my RecyclerView. I'm loading directly from network so I don't have any intermediate in-memory cache or database. Whenever something changes I call invalidate() on DataSource (in my case PositionalDataSource) so that the list is refreshed.

What I need is very simple thing - once I call invalidate() the recycler view is fully cleaned up and shows empty data. I need the recycler view to keep the old data and update normally once the new data comes in. In most of the cases the update might be very small, like a button color change in couple of rows, it looks ugly when the RecyclerView shows empty content for couple of seconds while I'm loading data from backend.

Can this somehow be done or is there a conceptual limitation of the current Paging library architecture forcing me to implement my own caching?

frangulyan
  • 3,580
  • 4
  • 36
  • 64
  • If you are loading directly from network, then how is it a `PositionalDataSource` and not an ItemKeyed or PageKeyed data source? – EpicPandaForce Apr 17 '20 at 14:38
  • that's the api of the backend, the request has parameters for start index and count – frangulyan Apr 17 '20 at 22:47
  • I believe the `LiveData>` should be able to hold on to the previous value unless it is overwritten by a new one from the DataSource. I guess the real question is why you get a new PagedList just by invalidating but having no data yet. If it's forced, maybe the empty response can be ignored...? – EpicPandaForce Apr 18 '20 at 00:21
  • Well, the only way to trigger data loading is to invalidate the data source. But whenever I do that the recycler view cleans up the UI. There is a `detach` function in `PagedList` which allows to keep the old state of the recycler view once I detect that I need to reload my objects. However, after detach nothing will happen since backend calls are triggered by PagedList automatically. – frangulyan Apr 18 '20 at 23:56
  • 1
    I think there is a conceptual problem, that's why Android is cleaning up the UI after invalidation. Imagine I loaded 20 objects and after some time realized that object number 5 needs to be fetched from backend again. I would invalidate data source and Recycler view would start fetching objects from backend, but keeps the old UI, as I want. If fetching takes too long - I could scroll up and down and mess everything, recycler view would need to fetch again, based on current scroll location since loading of the items depends on UI context. The only way is to have 1 source of truth - local cache. – frangulyan Apr 19 '20 at 00:03

1 Answers1

0

calling notifyDataSetChanged instead of invalidate may help as a simple solution.

ygngy
  • 3,630
  • 2
  • 18
  • 29
  • But that will not trigger data refreshing from my backend. I want the Paging library to stay in control of loading data. Imagine I scrolled to position 100-120 then something happens which can potentially change the data. Calling `invalidate` will trigger a network call to my backend to fetch items 100-120, while calling `notifyDataSetChanged` just signals the recycler view to redraw items. However, those items were not yet changed since nothing has triggered new backend fetch. – frangulyan Apr 16 '20 at 21:29