https://kotlinlang.org logo
d

Daniele B

10/05/2020, 1:14 PM
I was reading that in 1.0.0-alpha04, the
LazyColumnFor
issue about remembering the scrolling position was fixed. But I just checked and it’s not, at least not automatically. My use case is very simple: a list of elements; click on one element to display the detail page; going back to the list; the position is reset to the top, and not kept So, do we need to explicitly set that it should be remembered? And How? I mean that would be strange, as in the normal Android view system, the list scroll position is remebered when you go back to the list screen.
a

Andrey Kulikov

10/05/2020, 1:24 PM
it is not related to
LazyColumnFor
, if you navigate between screens with just if statements their state is lost when you switch the condition. it will be solved with a navigation library integration in the future
d

Daniele B

10/05/2020, 2:03 PM
@Andrey Kulikov
Copy code
Scaffold(
        topBar = {
            MasterTopBar(state = state)
        },
        bodyContent = { paddingValues -> LazyColumnFor(
            contentPadding = paddingValues,
            items = state.countriesListData.list
        ) { row ->
            MasterListRow(row, model)
        }
        },
        bottomBar = {
            MasterBottomBar(model = model, state = state)
        }
    )
actually there is not if statement
z

Zach Klippenstein (he/him) [MOD]

10/05/2020, 2:54 PM
How are you navigating between screens though? This code just shows one screen.
d

Daniele B

10/05/2020, 3:54 PM
I am accessing the detail screen by clicking on the list item, and I am coming back to the list screen with the Back button.
z

Zach Klippenstein (he/him) [MOD]

10/05/2020, 4:16 PM
What mechanism are you using to change screens though? Do you have a backstack? Are you using Jetpack Navigation? compose-router? Something else?
d

Daniele B

10/05/2020, 4:18 PM
I am simply using this:
Copy code
@Composable
fun ScreenRouter(coreModel: CoreViewModel) {
    val state by coreModel.stateFlow.collectAsState()
    if (state.detailState.selectedCountry == null) {
        MasterView(model = coreModel, state = state.masterState)
    } else {
        DetailView(model = coreModel, state = state.detailState)
    }
}
when I am in the Detail screen and I hit Back, a function on the coreModel is called, which changes the app state, by setting
detailState.selectedCountry
to null
z

Zach Klippenstein (he/him) [MOD]

10/05/2020, 4:47 PM
That’s the “if statement” that Andrey was talking about.
d

Daniele B

10/05/2020, 4:51 PM
OK, I see it now 🙂 So, while waiting for the navigation library to be ready, is there a way to save and reestablish the list scroll position in the meantime?
z

Zach Klippenstein (he/him) [MOD]

10/05/2020, 5:12 PM
You can wire up a
UiSavedStateRegistry
yourself, although that’s not trivial. There are a couple alternative navigation libraries at this link which support it already: https://foso.github.io/Jetpack-Compose-Playground/compose_projects/#libraries
d

Daniele B

10/05/2020, 5:23 PM
What about the
LazyListState
you were mentioning a few days ago? I was thinking it allowed to save the list state into an object, combined with a function to reestablish the scroll position?
z

Zach Klippenstein (he/him) [MOD]

10/05/2020, 5:30 PM
rememberLazyListState()
already does what is needed to support saving and restoring itself – it uses `rememberSavedInstanceState`: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-master-dev:compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt;l=71?q=rememberLazyListState&sq= However,
rememberSavedInstanceState
requires a
UiSavedStateRegistry
to be provided in the
UiSavedStateRegistryAmbient
, and for the state to actually be saved before it skips/gets removed from the composition. When you’re skipping it by just using a simple
if
, that’s not happening. These other navigation libraries all detect that a screen is about to be skipped, and do all the work to ask the registry to save stuff before skipping. That’s why the scroll position isn’t being saved in your case.
d

Daniele B

10/05/2020, 5:55 PM
Thanks for the explanation! It’s definitely not trivial 🙂 I guess I will wait for the official navigation library.
s

Se7eN

10/06/2020, 4:14 PM
@Zach Klippenstein (he/him) [MOD]
compose-router
doesn't save the state for me tho
z

Zach Klippenstein (he/him) [MOD]

10/06/2020, 4:15 PM
Huh, I thought it did.
compose-backstack
definitely does, but i need to update the compose version and do a release
3 Views