Mark
07/02/2026, 3:11 AMLazyColumn or LazyRow, I sometimes prepend a new item to the list.
By default, if the list is already scrolled to the start, the new item ends up off-screen (above or to the left). I assume this is because Compose preserves the currently visible item (what was index 0 is now index 1) rather than preserving the scroll position.
What I'd like instead is: if the user is already at scroll position 0, then after prepending an item, keep the scroll position at 0 so the new first item is immediately visible. (If the user has scrolled away from the start, I want the default behavior of preserving the visible content.)
Is there a built-in way to achieve this, or is manually calling scrollToItem(0) after detecting that the list was at the start before the update the recommended approach?Rabindra Khadka
07/02/2026, 7:04 AMscrollToItem(0) (or animateScrollToItem(0)) after the update. Otherwise, let Compose preserve the current position.Mark
07/05/2026, 5:12 AMval firstItemKey = items.firstOrNull()?.first
val wasAtStart = remember(firstItemKey) {
state.firstVisibleItemIndex == 0 && state.firstVisibleItemScrollOffset == 0
}
LaunchedEffect(firstItemKey) {
if (wasAtStart && items.isNotEmpty()) {
state.animateScrollToItem(0, 0)
}
}Rabindra Khadka
07/05/2026, 9:03 AMSean Proctor
08/10/2026, 12:33 PMvar sticky by remember { mutableStateOf(true) }
val lastSerial = lines.lastOrNull()?.serialNumber
LaunchedEffect(lastSerial) {
if (lastSerial != null && sticky) {
lines.lastIndex.takeIf { it > -1 }?.let { index ->
scrollState.scrollToItem(index)
}
}
}
LaunchedEffect(scrollState.lastScrolledBackward, scrollState.canScrollForward) {
// If the user scrolled back and they can scroll forward, stop being sticky
// if the window can't be scrolled forward, be sticky again
if (scrollState.lastScrolledBackward && scrollState.canScrollForward) {
sticky = false
} else if (!scrollState.canScrollForward) {
sticky = true
}
}
untested reversal:
var sticky by remember { mutableStateOf(true) }
LaunchedEffect(firstItemKey) {
if (sticky && items.isNotEmpty()) {
scrollState.animateScrollToItem(0, 0)
}
}
LaunchedEffect(scrollState.lastScrolledBackward, scrollState.canScrollForward) {
// If the user scrolled back and they can scroll forward, stop being sticky
// if the window can't be scrolled forward, be sticky again
if (scrollState.lastScrolledForward && scrollState.canScrollBackward) {
sticky = false
} else if (!scrollState.canScrollBackwaard) {
sticky = true
}
}