'But really, how does the AndroidX Paging Library know when to load more pages?
There's this question, which is identically worded.
But the poster's problem was solved without actually answering the question posted - because the problem was due to something unrelated to how the Paging Library knows to load more pages.
I'm wondering if the subscription/collection (Rx/Flow) mechanism used to consume the Paging datasource is how the Paging datasource knows when to load more pages. So maybe subscription/collection pulls pages. (But even so, how would pages after the initial load be triggered?) And the datasource can use the pull events as an opportunity to check if it needs to load more pages.
I'm just speculating here because I don't know how this all works internally.
I'm hoping someone will either verify or dismiss my speculation and provide greater detail about the mechanism involved. In particular, when the Pages are exposed as a Flow or (Rx) Flowable.
Solution 1:[1]
There's a LOT of code in the Paging 3 library, and I desperately wanted to avoid having to look at it too closely.
But I did some superficial exploration and found a likely candidate to explain how loads of missing pages are triggered by the user scrolling.
Loads aren't, as I speculated in my question, triggered by the activity of the subscription/collection (Rx/Flow) of pages.
The adapter's attempt to get an item to display triggers a call toPagingDataDiffer<T : Any>.get(@IntRange(from = 0) index: Int): T?
.
Its Javadoc:
Returns the presented item at the specified position, notifying Paging of the item access to trigger any loads necessary to fulfill prefetchDistance.
Params: index - Index of the presented item to return, including placeholders.
Returns: The presented item at position index, null if it is a placeholder.
Of particular interest:
... notifying Paging of the item access to trigger any loads necessary to fulfill prefetchDistance.
So, there we have it.
If others disagree or wish to elaborate on the mechanism, please do so.
Solution 2:[2]
The presenter API's .get(index)
call is what triggers item access to the rest of Paging. Generally you need to call this function in order to bind items to a RecyclerView.Adapter
, but leanback and compose work similarly.
On item access, an internal object called ViewportHint
is sent which contains presenter-state including how many items post-transformation you can see and your current position in the list, which can be handled asyncly from rest of UI.
Paging then essentially triggers loads based on PagingConfig.prefetchDistance
, but has a lot of logic handling race conditions, access conflation, cancellations, tracking load state, error handling, etc. which all can affect what ends up getting loaded in the end.
If you want to access but avoid triggering loads, there are .peek()
and .snapshot()
APIs that let you inspect presenter state without fetching.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | dlam |