I have a usecase where I would like a LazyColumn
to scroll to the top if a new item is added to the start of the list - but only if the list was scrolled to top before. I'm currently using keys for bookkeeping the scroll position automatically, which is great for all other cases than when the scroll state is at the top of the list.
This is similar to the actual logic I have in the app (in my case there is however no button, showFirstItem
is a parameter to the composable function, controlled by some other logic):
var showFirstItem by remember { mutableStateOf(true) }
Column {
Button(onClick = { showFirstItem = !showFirstItem }) {
Text("${if (showFirstItem) "Hide" else "Show"} first item")
}
LazyColumn {
if (showFirstItem) {
item(key = "first") {
Text("First item")
}
}
items(count = 100,
key = { index ->
"item-$index"
}
) { index ->
Text("Item $index")
}
}
}
As an example, I would expect "First item" to be visible if I scroll to top, hide the item and them show it again. Or hide the item, scroll to top and then show it again.
I think the solution could be something with LaunchedEffect
, but I'm not sure at all.
I did it like this:
@Composable
private fun ListOfItems(
items: List<Item>,
) {
val state = rememberLazyListState()
LaunchedEffect(items) {
snapshotFlow { state.firstVisibleItemIndex }
.collect {
// Scroll to the top if a new item is added.
// (But only if user is scrolled to the top already.)
if (it <= 1) {
state.scrollToItem(0)
}
}
}
LazyColumn(
state = state,
) {
// contents
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With