0

So I've been interacting with the paging 3 library lately and i learned a lot about it, but there are a few things that are still pretty difficult to grasp. My question is divided in a couple of points, the first might be a bug, the second purely informative.

First point: I've noticed that setting initialLoadSize to the same size as page size (i didn't try other values) makes the adapter jump around when it's done loading (meaning that the offscreen loading starts moving the list position around when not interacting) if this is not a bug, the first point is "how (and with which user settable parameters) does the adapter determine when to move the list around (what item to center) after a load.

Second point: To fix the behavior in point one i have restored the initialLoadSize to default. I also have the need to implement my own paging source that interacts with room (because due to some application logic i need to load some items further in the list before they would be loaded by paging, and this stops paging from loading any more item after these) and i cannot figure out how how to handle all the edge cases in the paging source (like when to set next and previous key to null, and when to set items before and items after, based on what params). So to understand this better maybe someone could explain how the parameters interact together.

I should probably clarify that i also use a remote mediator and that I'm wrapping a room paging source in my own paging source.

The project i'm working on at the moment is this: https://gitlab.com/sedestrian/pokedex in the "develop" branch under the "Restored paging source logic" commit.

Thanks in advance.

alessandro gaboardi
  • 889
  • 3
  • 11
  • 26

1 Answers1

0

I've noticed that setting initialLoadSize to the same size as page size (i didn't try other values) makes the adapter jump around when it's done loading (meaning that the offscreen loading starts moving the list position around when not interacting) if this is not a bug, the first point is "how (and with which user settable parameters) does the adapter determine when to move the list around (what item to center) after a load.

What do you mean by jump around? Before initial load, there isn't any data right?

I'm guessing you mean in the invalidate / config change case - on refresh, in order for diffutil to preserve your position, you need to load about the same position where the user is currently viewing PagingState.anchorPosition, so you must implement PagingSource.getRefreshKey in a way that will provide a key to subsequent refresh, that at least fills the current viewport centered on PagingState.anchorPosition. Larger initialLoadSize will allow you to be a bit more flexible in terms of how far away your key is, so that's one possible scenario where changing the size would cause it to "jump".

To fix the behavior in point one i have restored the initialLoadSize to default. I also have the need to implement my own paging source that interacts with room (because due to some application logic i need to load some items further in the list before they would be loaded by paging, and this stops paging from loading any more item after these) and i cannot figure out how how to handle all the edge cases in the paging source (like when to set next and previous key to null, and when to set items before and items after, based on what params). So to understand this better maybe someone could explain how the parameters interact together.

You can trigger manual loading by simply calling adapter.getItem(index) or differ.get(index). This is how bind essentially triggers loading in Paging, however you need to be careful of PagingConfig.maxSize, because loading too far ahead can cause pages in the viewport to drop so that Paging can respect maxSize, while still loading the requested pages.

null should be set on nextKey and prevKey in cases where there is no more to load and you've reached the end of the dataset (last or first page).

itemsBefore and itemsAfter is used to control the number of placeholders, this count is essentially ignored if PagingConfig.enablePlaceholders is disabled, and in that case it's better to leave the default value of undefined. This is used for counted datasets. Please read the official docs as there's some info there that might be helpful to you: https://developer.android.com/reference/kotlin/androidx/paging/PagingSource.LoadResult.Page

dlam
  • 3,547
  • 17
  • 20
  • Yes I've read the documentation, but found that it's not exactly what happens. The combination of prev/next key and items before/after as well as number of loaded items and load type is used to trigger remote loads and present results in the adapter. What i have observed is this: https://gist.github.com/sedestrian/83902b0b9089bcf86e7e33dcb61c1d9e This loads everything correctly – alessandro gaboardi Feb 05 '21 at 22:25
  • I adapted my code to follow the results observed and managed to make it work, but it was really mimiking and not understanding much of what i was doing – alessandro gaboardi Feb 05 '21 at 22:28
  • 1
    Ah yes - with `RemoteMediator` it is essentially just a callback triggered when `PagingSource` reaches the end, and to mark the end of remote loads, you simply return `RemoteMediator.Succes(endOfPaginationReached = true)`. But all visible data is actually driven by `PagingSource` and loads within local source are driven by `nextKey` / `prevKey` – dlam Feb 06 '21 at 01:47
  • I think i also noticed that items after and items before tell paging what page to focus on after the load (what page to center on screen) but I'm not really sure. When passing wrong parameters things like this happen: https://youtu.be/QePyT2fN7J8 – alessandro gaboardi Feb 06 '21 at 08:40