Nino
03/13/2025, 9:29 AMArne Jans
03/13/2025, 12:49 PMandroidx.paging:paging-compose
artifact to integrate Paging with your UI layer instead. To learn more, see the API documentation for collectAsLazyPagingItems()
.
from https://developer.android.com/topic/libraries/architecture/paging/v3-overview#uiArne Jans
03/13/2025, 1:32 PMIan Lake
03/13/2025, 2:07 PMRok Oblak
03/13/2025, 8:42 PMNino
03/14/2025, 8:03 AMIan Lake
03/14/2025, 2:06 PMBut there's so much stuff that I have to do that I can't do with Paging3
Can you give some examples?
Nino
03/14/2025, 2:50 PM{
"items": [
...
],
"totalCount": 140
}
So in my PagingSource.load()
function, for the first page, I have to create an extra "item" on top and wrap other "real items" on the first page.
LoadResult.Page(
data = if (page == 0) {
buildList {
add(
Wrapper.Header(totalCount = response.totalCount)
)
addAll(response.items.map { Wrapper.Content(it) })
}
} else {
response.items.map { Wrapper.Content(it) }
},
...
)
That's basically doing UI stuff in the data layer. No separation of concerns there. ๐
2/ We have an MVI Architecture so it breaks every principle around it. Can't access the data that is inside the flow, can't have a single source of truth out of the ViewModel, can't refresh or reload the data from the ViewModel, we have to trust the view, etc.
3/ Tracking events is hard. There's no way to know the view requested more data outside of the PagingSource, and exposing those state is doing half of the job I'd have to do to do paging myself anyway so...
And that's only the first issues I encountered in 24 hours so I guess there will be more.Rok Oblak
03/14/2025, 2:55 PMNino
03/14/2025, 3:05 PMArne Jans
03/27/2025, 2:23 PMLazyColumn
.
You can simply insert a header-item directly in the Compose-code:
LazyColumn {
item {
Header(totalCount)
}
items(...) {
...
}
}
Arne Jans
03/27/2025, 2:26 PMHeader
to always be visible, you can put the Header
into a non-scrollable Column
with fillMaxSize()
and the LazyColumn
as the second Composable
in the Column
.Nino
03/27/2025, 4:30 PMtotalCount
value in Compose that is coming from the backend endpoint? I would need to put that information in the LoadResult.Page.data field, wouldn't I?Ian Lake
03/27/2025, 4:35 PMLoadResult.Page
lets you set the itemsBefore
and itemsAfter
, so you already have the totalCount of all items just by looking at the lazyPagingItems.itemCount
(assuming you have placeholders turned on for Pager, which you absolutely should)Nino
03/27/2025, 4:37 PMlazyPagingItems.itemCount
gives me the total loaded content sizeIan Lake
03/27/2025, 4:37 PMlazyPagingItems.itemCount
is the total loadable content sizeNino
03/27/2025, 4:39 PMIan Lake
03/27/2025, 4:40 PMThelets you set theLoadResult.Page
anditemsBefore
itemsAfter
Ian Lake
03/27/2025, 4:43 PMitemsBefore
to 0
and itemsAfter
to totalCount - 20
, now Paging knows how many total items you haveNino
03/27/2025, 4:49 PMlazyPagingItems.itemCount
to send to the tracking team how many items were seen / loaded...Ian Lake
03/27/2025, 4:53 PMlazyPagingItems.itemSnapshotList.items.size
since that is defined as:
The presented data, excluding placeholders.
Ian Lake
03/27/2025, 4:53 PMPagingConfig
you pass to your Pager
(specifically, maxSize
and jumpThreshold
)Ian Lake
03/27/2025, 4:57 PMIan Lake
03/27/2025, 4:58 PMValentin Gusselnikov
03/27/2025, 4:58 PMIan Lake
03/27/2025, 5:00 PMI thought the totalCount is basically a count of all items across all pages. If this is true, then you're right you have to create some models in your domain and wrap your data (I'm doing the same thing)No, you don't, as per the above - Paging lets you track the total items already
Valentin Gusselnikov
03/27/2025, 5:02 PMIan Lake
03/27/2025, 5:03 PMitemsAfter
correctly. You can't lieValentin Gusselnikov
03/27/2025, 5:06 PMNino
03/27/2025, 5:07 PMLoadResult.Page.itemsAfter
with the totalCount (from backend) - actual server response size - actual list size, I can use itemCount
for the total loadable item count?
And for the tracking (I'm using compose), using a LaunchedEffect
keyed with the itemSnapshotList.items.size
will get me the best approximation of how much content has been seen (up to loadSize items) ?Ian Lake
03/27/2025, 5:07 PMIan Lake
03/27/2025, 5:09 PMSo for the header, if I provideYep, as long as you have placeholders enabled in your Pager and fill inwith the totalCount (from backend) - actual server response size - actual list size, I can useLoadResult.Page.itemsAfter
for the total loadable item count?itemCount
itemsBefore
and itemsAfter
, Paging will report the correct itemCount
for your entire dataset
And for the tracking (I'm using compose), using aYep, that would contain the total number of currently loaded itemskeyed with theLaunchedEffect
will get me the best approximation of how much content has been seen (up to loadSize items) ?itemSnapshotList.items.size
Nino
03/27/2025, 5:11 PMValentin Gusselnikov
03/27/2025, 5:15 PMIan Lake
03/27/2025, 5:22 PMpageNumber
field to your data classes (which would allow you to do if (before.pageNumber != after.pageNumber && after.pageNumber % EVERY_PAGE_COUNT == 0)
, it isn't like you are somehow prohibited from doing thatValentin Gusselnikov
03/27/2025, 5:24 PM