Status Update
Comments
st...@viber.com <st...@viber.com> #2
Branch: androidx-main
commit 16278c75a09262bfc2b1e230730f79ec5a4d4918
Author: Andrey Kulikov <andreykulikov@google.com>
Date: Tue May 25 18:25:16 2021
Do not reset initial scroll position in LazyColumn/Row when items are loaded asynchronously
If the initial scroll position(or restored scroll position) is not 0 this value will be immediately overridden by 0 if there were no items yet provided for LazyColumn/Row.
It is easily reproducible with Paging where we start loading asynchronously and there is always a first frame when we don't have any items.
Fixes: 177245496
Test: new tests for LazyColumn and LazyRow
Change-Id: I95e374fb06dc480aab7b56b8b3cacb92ca1188a9
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnTest.kt
M compose/foundation/foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowTest.kt
M compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt
cl...@google.com <cl...@google.com> #3
ap...@google.com <ap...@google.com> #4
Yes, we basically just changed the default behavior for the empty case for now. Please track this bug
cl...@google.com <cl...@google.com> #5
My workaround currently is to keep `LazyPagingItems` object in `ViewModel`, so that `itemCount` and other state will be the same when navigated back.
pr...@google.com <pr...@google.com> #6
yes, it is expected as the paging is starting loading asynchronously and there is always at least one frame when there is no items yet
va...@gmail.com <va...@gmail.com> #7
cl...@google.com <cl...@google.com> #8
so we can discuss this separately.
Thanks!
ma...@kayak.com <ma...@kayak.com> #9
Where can I find the new bug? this issue affect me as well.
cl...@google.com <cl...@google.com> #10
Can you provide an example? In my case stored `LazyPagingItems` object does not want to load data
upd: No longer needed. In my case the issue with LazyVerticalGrid. For myself I found solution - I made copy of LazyPagingItems to make counstructor public and create LazyPagingItems inside ViewModel, so reloading does not occur when navigating backwards
ja...@go-text.me <ja...@go-text.me> #11
cl...@google.com <cl...@google.com> #12
You probably want to try to use `.cachedIn(viewModelScope)`. See
ja...@go-text.me <ja...@go-text.me> #13
I mean that `.cachedIn(viewModelScope)` in the ViewModel solved my scroll state issue.
va...@gmail.com <va...@gmail.com> #14
In my case .cachedIn(viewModelScope)
preserves data from loading again, but scroll position is still resetting to the start every time I navigate to another composable and back. I use LazyColumn
with header (item
element before items
), so that might be the case
cl...@google.com <cl...@google.com> #15
Check if you have any other item in the LazyList outside the paged items it will lose position.
If you have any comment it out and see if it still lose position.
va...@gmail.com <va...@gmail.com> #16
We are using paging 3 for loading with LazyPagingItems.
var listState: LazyListState //declared in the viewmodel
sample:
LazyColumn(
state = listState,
modifier = Modifier
.fillMaxWidth()
) {
items(items = lazyListingItems,)
{
ListingCard(), onClick = {
navHostController.navigate(Routes.detail)
}
)
}
}
Please help to solve this.
pk...@tango.me <pk...@tango.me> #17
I think what happens is when you go to other screen your state still exist together with the ViewModel, then when you go back to the original screen lazyListingItems are recreated, and as Paging provides the values via a Flow there is no way to get the data synchronously, so there is always at least the first frame where lazyListingItems has 0 items yet, then LazyColumn is populated with 0 items so it has to reset the scroll position. It can't differentiate between the events where there are no items anymore and there are no items yet.
But if the LazyListState will be recreated as part of the recomposition then it can postpone the scroll position restoration till the first frame when there are at least 1 element in the list
Description
Despite the fact that bug https://issuetracker.google.com/issues/343124454 is marked as fixed, it's still reproduced after updating from 3.2.1 to 3.3.4. I created a sample project to demonstrate it.
Steps to reproduce:
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 156(offset:156).state:1000 androidx.recyclerview.widget.RecyclerView{e95134d VFED..... ........ 0,367-1080,2205 #7f08016c app:id/recycler}, adapter:com.example.badsearch.MainRecyclerAdapter@be8de02, layout:androidx.recyclerview.widget.LinearLayoutManager@d575313, context:com.example.badsearch.MainActivity@3b66302 at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6364) at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:288) at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:345) at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:361) at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:368) at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:399) at android.os.Handler.handleCallback(Handler.java:958) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:230) at android.os.Looper.loop(Looper.java:319) at android.app.ActivityThread.main(ActivityThread.java:9063) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:588) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)