Status Update
Comments
ae...@google.com <ae...@google.com>
an...@google.com <an...@google.com>
du...@google.com <du...@google.com> #2
ri...@gmail.com <ri...@gmail.com> #3
Also adding that I notice a crash while repro-ing this:
2021-01-25 11:47:32.315 17990-17990/paging.android.example.com.pagingsample E/AndroidRuntime: FATAL EXCEPTION: main
Process: paging.android.example.com.pagingsample, PID: 17990
java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
at java.util.ArrayList.get(ArrayList.java:437)
at androidx.paging.PageFetcherSnapshot.doLoad(PageFetcherSnapshot.kt:370)
at androidx.paging.PageFetcherSnapshot$collectAsGenerationalViewportHints$$inlined$collect$1.emit(Collect.kt:133)
at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:61)
at kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Unknown Source:11)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7660)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2021-01-25 11:47:32.501 14519-14615/com.google.android.googlequicksearchbox E/MDD: DownloadProgressMonitor: Can't find file for uri: android://com.google.android.googlequicksearchbox/files/sharedminusonemodule/shared/SharedMinusOneData.pb.tmp
2021-01-25 11:48:08.376 2197-9975/com.android.phone E/PhoneInterfaceManager: [PhoneIntfMgr] getCarrierPrivilegeStatus: Invalid subId
2021-01-25 11:48:28.470 914-914/? E/BatteryDefender: Failed to read /sys/class/power_supply/wireless/online
ri...@gmail.com <ri...@gmail.com> #4
For #3, filed separately here:
an...@google.com <an...@google.com> #5
Hmm so I thought about this for awhile and it seems quite difficult to solve - essentially what is happening is we are prepending more items than there are number of placeholders due to the addition of separators, so it's impossible to scroll to the top before prepending because we don't know how many items to scroll up by. Basically the placeholders don't map 1:1 to the original item, so we have to decide how and where to notify RV that there are extra items and the current behavior for prepend is to always send the onInserted event to notify new items above the current position to handle the regular scrolling via swipe scenario.
In the swipe scroll case, user wants to see the bottom items from prepended page first, and then have extra items added above the scroll position, but in the scroll to top case we want to see the top items first, and then add extra items to the bottom. Since scrollToPosition always puts the desired index to position at the top, we need some way to tell paging that if we prepend due to call to scrollToPosition, we basically need to switch the order of the differ events to work like append instead.
As a simple workaround, you can set jumpThreshold
in PagingConfig
to be the same as maxSize
, and this will cause paging to use the refresh / invalidate flow to load from the scrollToPosition index (which is what you want anyway in large jumps instead of prepending until you get there).
ri...@gmail.com <ri...@gmail.com> #6
Maybe there's another way to look at this. Is there a way to 'reset' the RecyclerView, the PagingDataAdapter and PagingSource that's coming from Room, so that they ignore anything that's happened up to now (any scrolling or loading different pages from the db), and behave as if they've just been bound for the first time again?
an...@gmail.com <an...@gmail.com> #7
I'm afraid this is also hard for recyclerview (both both smooth and non-smooth scroll).
Basically, when you try to scroll to a position, recyclerview just lays out in that position. but if paging adds more items above, that happens after RecyclerView scrolls. The same thing happens if you try to scroll to a non-existing position (e.g. you only have 50 in memory and you scroll to 100) It will just stop 50.
Due to the nature of this problem (not knowing when data will stop coming), a possible solution is to actually write a custom scroller over recyclerview that keeps pushing it to 0 as items are loaded.
For jump scenerios, it might be even better to just get a new paging flow that starts w/o an initial key and also set a new adapter on the recyclerview (so that it does not try to diff). If you use the same adapter, you can consider calling notifyDataSetChanged when list is updated on the adapter, that should fool RecyclerView to just render from scratch.
de...@gmail.com <de...@gmail.com> #8
to...@gmail.com <to...@gmail.com> #9
Without stable list, jumping won't really be feasible. I think the only way it can work is to create a new pager w/ an initial key to restart the data from that location (combined w/ scrollToPosition(0) )
ke...@gmail.com <ke...@gmail.com> #10
While playing with my workaround I noticed it only works in some cases and as there is a separate bug causing multiple jumps to happen on scroll to top. This is why it ends up scrolling downwards after jumping to the top due to jumping.
I believe the root cause is due to conflated hints causing new generation to reload a second time.
ja...@gmail.com <ja...@gmail.com> #11
So it looks like the second jump up is due to the differ events out of diffutil, it doesn't understand the overlap since the list sizes are mismatches so we need to add some special case handling in paging for this.
ma...@migrosonline.ch <ma...@migrosonline.ch> #12
Branch: androidx-main
commit 4eabdc68446c5268a9a6f1d80546703eba18d3b1
Author: Yigit Boyar <yboyar@google.com>
Date: Fri Mar 05 10:47:07 2021
Improve NullPaddedList diffing
This CL updates NullPaddedList diffing heuristic to better optimize for
common cases.
There two common cases we optimize for:
a) For completely distinct lists, we dispatch them as change animations
whenever possible based on positions (as long as there is no item in the
same global position in the old and new list)
b) For cases where lists partially overlap, we use available
placeholders to dispatch inserts or convert removals to placeholders
WHEN those updates happen at the boundaries of the list. This especially
handles cases where placeholders are loaded and prevents recyclerview
from scrolling to keep placeholders on screen.
See NullPaddedDiffing.md document for more details.
Bug: 170027529
Bug: 177338149
Test: NullPaddedListDiffWithRecyclerViewTest
Test: AsyncPagedListDifferTest
Test: NullPaddedListDiffHelperTest
Relnote: "We've rewamped how placeholders are handled when list is
reloaded to prevent unexpected jumps in RecyclerView. See
NullPaddedDiffing.md for details."
Change-Id: If1490f5bc833a61793d27eeaae9b37b26153df87
M paging/common/api/public_plus_experimental_3.0.0-beta03.txt
M paging/common/api/public_plus_experimental_current.txt
M paging/common/src/main/kotlin/androidx/paging/PagingDataDiffer.kt
M paging/runtime/build.gradle
M paging/runtime/src/androidTest/java/androidx/paging/AsyncPagedListDifferTest.kt
M paging/runtime/src/androidTest/java/androidx/paging/AsyncPagingDataDifferTest.kt
M paging/runtime/src/androidTest/java/androidx/paging/NullPaddedListDiffHelperTest.kt
A paging/runtime/src/androidTest/java/androidx/paging/NullPaddedListDiffWithRecyclerViewTest.kt
M paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.kt
A paging/runtime/src/main/java/androidx/paging/NullPaddedDiffing.md
M paging/runtime/src/main/java/androidx/paging/NullPaddedListDiffHelper.kt
be...@swile.co <be...@swile.co> #13
After this change - setting jump threshold now works as expected :)
be...@swile.co <be...@swile.co> #14
(I'm on Chipmunk Beta 2)
th...@palringo.com <th...@palringo.com> #15
da...@gmail.com <da...@gmail.com> #16
With compose 1.2.0-beta01, constructing a static LazyPagingItems like this works for me in interactive preview.
val ordersFlow = flowOf(PagingData.from(orders))
val pagingItems = ordersFlow.collectAsLazyPagingItems()
However, the static preview will only show an empty list of items.
wo...@gmail.com <wo...@gmail.com> #17
I still cannot preview the list. Interactive preview doesn't show it as well.
du...@google.com <du...@google.com> #18
Preview doesn't work in paging-compose at the moment with PagingData
because it has to wait for some work to be done before any items show up, so the first frame is always empty as mentioned in #5. However, it's worth investigating if we can get it to work with static PagingData
like PagingData.from
ai...@googlemail.com <ai...@googlemail.com> #19
ro...@cloudkitchens.com <ro...@cloudkitchens.com> #20
ki...@gmail.com <ki...@gmail.com> #21
+1 our snapshot tests became useless after moving from unpaged lists to paged lists, would be really nice to have a preview functionality so our snapshot tests can keep working
lu...@gmail.com <lu...@gmail.com> #22
Please reopen.
ki...@gmail.com <ki...@gmail.com> #23
Would be great to reopen this or give a reason why it won't be fixed. Seems like an important functionality since like it currently stands we cannot cover paged lists with paparazzi snapshot tests.
cl...@google.com <cl...@google.com> #24
Reopening as it's something we would want for paging-compose.
Paging currently can't support this because as
[Deleted User] <[Deleted User]> #25
[Deleted User] <[Deleted User]> #26
di...@gmail.com <di...@gmail.com> #27
cl...@google.com <cl...@google.com> #28
We are planning to include preview support as part of stable paging-compose.
ri...@gmail.com <ri...@gmail.com> #29
Any dates/timelines?
cl...@google.com <cl...@google.com> #30
Currently planned for Q2/Q3.
ap...@google.com <ap...@google.com> #31
Branch: androidx-main
commit 15fa26db22d9a0d2e00cb3847620bc6ae08561fc
Author: Clara Fok <clarafok@google.com>
Date: Mon May 01 16:53:10 2023
Add support for Paging preview in compose
Paging Compose now supports previewing a list of fake data by creating a PagingData.from(fakeData) and passing the PagingData to a MutableStateFlow. Call the MutableStateFlow<PagingData<Value>>.collectAsLazyPagingItems() to preview.
Test: ./gradlew paging:paging-compose:cC
Test: preview sample in PagingPreviewSample
Bug: 194544557
Relnote: "Paging Compose now supports previewing a list of fake data by creating a PagingData.from(fakeData) and passing the PagingData to a MutableStateFlow. Call the MutableStateFlow<PagingData<Value>>.collectAsLazyPagingItems() to get previewable LazyPagingItems."
Change-Id: I8a78db059776190b833773986825579e96e042d5
M paging/paging-common/src/main/kotlin/androidx/paging/PagingData.kt
M paging/paging-compose/build.gradle
M paging/paging-compose/samples/build.gradle
A paging/paging-compose/samples/src/main/java/androidx/paging/compose/samples/PagingPreviewSample.kt
A paging/paging-compose/src/androidTest/java/androidx/paging/compose/LazyPagingItemsPreviewTest.kt
M paging/paging-compose/src/main/java/androidx/paging/compose/LazyPagingItems.kt
cl...@google.com <cl...@google.com> #32
Fixed internally and will be available in the next Paging release. This bug will be updated with release version at the time.
k....@rebuy.com <k....@rebuy.com> #33
Is it already in 1.0.0-alpha19
? If yes, then could I get an example of how to use it?
cl...@google.com <cl...@google.com> #34
It will be available in the upcoming release on May 24th as paging-compose 1.0.0-alpha20
.
The change does include an example on how to set up
The example has DisplayPaging()
composable inlined within PagingPreview()
composable. This is ONLY FOR sample purposes because of how the @Preview
annotation is rendered in documents. In production code DisplayPaging()
should be its own separate, top-level declaration.
ju...@google.com <ju...@google.com> #35
The following release(s) address this bug.It is possible this bug has only been partially addressed:
androidx.paging:paging-common:3.2.0-alpha06
androidx.paging:paging-compose:1.0.0-alpha20
no...@gmail.com <no...@gmail.com> #36
One important point – inside @Preview
, you should use MutableStateFlow()
rather than builders like flowOf()
– the latter simply doesn’t work
Description
Jetpack Compose release version:1.0.0-rc02
Android Studio Build:Android Studio Bumblebee | 2021.1.1 Canary 4
Kotlin version:1.5.10
I think the title says it all.
LazyPagingItems
constructor is internal. I can't passLazyPagingItems
as parameter in Preview Composable, let alone passing sample data. But I want to show preview of my composable, how should I do this?