Daniele Segato
07/30/2021, 9:22 AMnavigation-compose 2.4.0-alpha05
and my LazyColumns were broken.
I've investigated and it looks like rememberSaveable
usage without a key has been broken. Upon navigation and back it is not restored because currentCompositeKeyHash
has changed.
This means rememberLazyListState()
doesn't work if you leave a list into a detail and than back it scrolls back up cause it creates a new LazyListState
@Ian Lake I'm tagging you because I saw you are on top of this kind of issues in other comments and I suppose this information can help you solve other issues with this release. If you do not want me to ping like that I won't do it again.
I can (and will) create a bug report: just do not have time now and just wanted to let you guys know of the issue as fast as I could. -- I'll link it here in a response
Other issues I noticed:
I had a login flow working like this:
routes:
• EntryPoint
• Login
• Registration
the Entry point sent directly to either login or registration with a LaunchedEffect
controlled by a StateFlow in the viewmodel. When entering the screen I would mark it to exit when coming back. This allowed me to handle the logic of setting backStackEntry arguments as results of the auth flow.
with the old navigation after navigating to login the launched effect didn't receive the "go back" event until the user re-entered the entry point screen while with alpha05 it immediately execute the back call.
This was fixed using lifecycle.whenStarted { }
to handle the navigation back -- but you might wanna mention this as side effect in the release notes.Daniele Segato
07/30/2021, 9:25 AMprintln("currentCompositeKeyHash = $currentCompositeKeyHash")
val lazyListState = rememberLazyListState()
Before entering detail
currentCompositeKeyHash = -1594222293
After going back from detail to the list
currentCompositeKeyHash = 1495893918
Daniele Segato
07/30/2021, 9:28 AMval navigateTo by authFlowViewModel.navigateTo.collectAsState()
val lifecycle = LocalLifecycleOwner.current.lifecycle
LaunchedEffect(key1 = navigateTo) {
when (navigateTo) {
AuthFlowNavigateTo.TargetNotAuthenticated -> {
lifecycle.whenStarted {
actions.navigateBackToTarget(authenticated = false)
}
}
AuthFlowNavigateTo.TargetAuthenticated ->
lifecycle.whenStarted {
actions.navigateBackToTarget(authenticated = true)
}
AuthFlowNavigateTo.Login -> {
actions.navigateToLogin()
authFlowViewModel.onEntryPointNavigated() // this trigger a change in navigateTo
}
AuthFlowNavigateTo.SignIn -> {
actions.navigateToSignIn()
authFlowViewModel.onEntryPointNavigated()
}
}
}
BackPressHandler {
actions.navigateBackToTarget(authenticated = false)
}
Ian Lake
07/30/2021, 1:11 PMIan Lake
07/30/2021, 1:13 PMIan Lake
07/30/2021, 1:15 PMIan Lake
07/30/2021, 1:30 PMflowWithLifecycle
(from the Lifecycle 2.4 alphas) on your navigateTo
flow to avoid collecting your flow at all when you aren't startedIan Lake
07/30/2021, 2:30 PMcollectAsState()
should be used for flows that represent state - something you can apply hundreds of times over in an idempotent way. Your navigateTo
flow seems like an event stream that you'd want to simply collect in a LaunchedEffectIan Lake
07/30/2021, 2:31 PMrepeatOnLifecycle
to run your collect only when started)Daniele Segato
07/30/2021, 2:32 PMcurrentCompositeKeyHash
changing?
That's the thing that I cannot workaroundDaniele Segato
07/30/2021, 2:33 PMColton Idle
07/30/2021, 6:38 PMKeep in mind that with animations (like the crossfade we have now), both your old and new destination are going to be recomposed multiple times as that animation happensThis seems like a great way to test that my composable isn't doing something wrong. 🙃
Daniele Segato
07/30/2021, 6:40 PMAndrey Kulikov
07/30/2021, 6:53 PMIan Lake
07/30/2021, 7:46 PMDaniele Segato
07/30/2021, 7:48 PMDaniele Segato
08/02/2021, 9:44 AMDaniele Segato
09/18/2021, 8:35 AM2.4.0-alpha08
which fixed the issue with currentCompositeKeyHash
changing.
I still had an issue with scroll position not being maintained when entering a detail from my list and coming back.
I noticed it was happening ONLY where I was using the paging-compose
library (version 1.0.0-alpha12
).
I had an header and footer in my LazyList so the structure was like this
val items = viewModel.pagedItems.collectAsLazyPagingItems()
LazyColumn(...) {
item { Header() }
items(items, ...) { ... }
item { Footer() }
}
simply removing the Header and Footer made the issue go away: the was scroll correctly restored
It looks like when the LazyColum restore its state it initially only find the Header and Footer items, it restores to a smaller list and thus when the paging items becomes available again it scrolled all the way up.
As a workaround I used .insertHeaderItem()
and .insertFooterItem()
but I don't think I should need it.
I plan to create a small project reproducing this and open a bug about itAndrey Kulikov
09/18/2021, 2:28 PM