Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

After DataSource.Invalidate() new PagedList has only one page

I have a list with pagination which I implemented using Paging library. Items on this list can be modified (changed/deleted). According to official documentation, I'm first changing in-memory list cache from which my DataSource gets pages and after that calling datasource.invalidate() in order to create new pair PagedList/DataSource:

If you have more granular update signals, such as a network API signaling an update to a single item in the list, it's recommended to load data from network into memory. Then present that data to the PagedList via a DataSource that wraps an in-memory snapshot. Each time the in-memory copy changes, invalidate the previous DataSource, and a new one wrapping the new state of the snapshot can be created.

It works and looks WELL if user modifies items on first page.

However, if user is on page two or further during datasource.invalidate() he will be thrown at the end of the first page.

Debugging shows this happens because new PagedList has only first page when it's submitted to PagedListAdapter.submitList. Adapter compares old and new lists and removes all items not from first page. It happens always but not visible for user if he is on the first page.

So to me, it looks like new pair PagedList/DataSource have no idea about number of pages which fetched previous pair and datasource.invalidate() doesn't fit for the situation in docs. Behavior that I see acceptable for cases then user updates all list (like swipe-to-refresh) but not

an update to a single item in the list

Has anybody faced such issue or somehow archived things I want? Maybe I'm missing some trick which helps me to get new PagedList already with all pages.

For clarification: library version 2.1.0. Custom PageKeyedDataSource based on in-memory cache and remote servise (No Room)

like image 864
ylus Avatar asked Feb 23 '19 22:02

ylus


Video Answer


1 Answers

I want to share my research in case anybody is interested:

  1. Issue ("lack of feature") is known, at least I've found the couple related discussions on official tracker one two
  2. If you are using PositionalDataSource or ItemKeyedDataSource you should dig into the direction of requestedStartPosition/requestedInitialKey from initial params as this answer says. I didn't have much time to build the whole solution but those params are indeed different for initial load after invalidation

About my case : PageKeyedDataSource. Here you can read that there is no similar to requestedInitialKey params in this type of data source. Still, I found a solution which fits me, very simple, although, feels like a dirty trick:

When loadInitial() is called after invalidate() in-memory cache returns all already loaded pages instead of just first one. At first I was worry that something will break if, for example, requestedLoadSize is 5 but the result is 50 items list but turns out it's just a hint and it can be ignored. Just don't forget to pass nextPageKey which corresponds to the last cached page and not the first one.

Hope it will help

like image 96
ylus Avatar answered Sep 27 '22 23:09

ylus