Does retaining a scroll position of a LazyRow via ...
# compose
a
Does retaining a scroll position of a LazyRow via LazyListState work without compose navigation?
I have a LazyRow which does not retain its scroll position when navigating to Fragment B and going back to Fragment A.
The interesting thing is: the firstVisibleItemIndex is correct after the first composition of the LazyRow. The LazyRow seems to be recomposed 3 Times. After the first composition the LazyListState.firstVisibleItemIndex is reset to zero.
a
do you have LazyRow items loaded asynchronously? it can reset to 0 if there are only 0 items
a
No, the LazyRow is initialized with all the items, which come from a List
a
also when you use ComposeView in Fragment you usually need to set
composeView.setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
a
Thanks, will try adding this 👍🏻
Copy code
fun CameraRoll(
    images: List<File>,
    onImageClick: (File) -> Unit,
    firstItemVisibleIndex: Int = 0,
    onFirstItemVisibleIndexChanged: ((Int) -> Unit)
) {
    val lazyListState = rememberLazyListState(firstItemVisibleIndex)

    if (images.isNotEmpty()) {
        LazyRow(
            modifier = Modifier
                .fillMaxSize(),
            verticalAlignment = Alignment.CenterVertically,
            state = lazyListState
        ) {
            items(images) {
                ImagePreview(
                    image = it,
                    onImageClick
                )
            }
        }

        DisposableEffect(lazyListState) {
            onDispose {
                onFirstItemVisibleIndexChanged.invoke(lazyListState.firstVisibleItemIndex)
            }
        }
    } else {
        NoContentInfo()
    }
}
@Andrey Kulikov Here is some code. The firstItemVisibleIndex is given to the composable via field. In my case, when returning to Fragment A where the LazyRow is held, the firstItemVisibleIndex is 4 and still the LazyRows Scroll position is on the very first item (index 0)
What am i doing wrong?
Copy code
SideEffect {
    scope.launch { lazyListState.scrollToItem(firstItemVisibleIndex) }
}
Even adding a SideEffect which explicitly scrolls the LazyRow to the firstItemVisibleIndex on each composition does not work
a
hm. why do you have that DisposableEffect? do you manually save the firstVisibleItemIndex in order to restore it? the state restoration is expected to work automatically, when there is state to restore the value you passed to rememberLazyListState() is ignored and instead the restored position is used
a
Well, this was my thought also, before trying all the side effects and manually storing the scroll position i was also expecting rememberLazyListState() to restore the scroll position automatically, but it just doesn’t do it
Copy code
fun CameraRoll(
    images: List<File>,
    onImageClick: (File) -> Unit
) {
    if (images.isNotEmpty()) {
        LazyRow(
            modifier = Modifier
                .fillMaxSize(),
            verticalAlignment = Alignment.CenterVertically
        ) {
            items(images) {
                ImagePreview(
                    image = it,
                    onImageClick
                )
            }
        }
    } else {
        NoContentInfo()
    }
}
So basically: this should automatically restore the scroll position right? Well, no, it doesn’t, for some reason
a
how do you switch fragments? will just regular savedInstanceState mechanism of fragments work like here https://developer.android.com/guide/fragments/saving-state
144 Views