Enable Auto-scrolling LazyColumn to the bottom when reverseLayout = false

12.7k Views Asked by At

I have a LazyColumn holding some Items. I listen a Flow from Room and everything works great when reverseLayout = true. When new Item get inserted into the database, the LazyColumn scrolls to the bottom and shows last Item just fine. But reverseLayout = true inverts the headers too. So I disabled it with reverseLayout = false. This does not work in that when Item get inserted, it is shown on the list but the list does not get scrolled to show the bottom item. I have to manually scroll.

How can I scroll to the bottom Item when the LazyColumn get recomposed on items change?

I don't think I need to put the code since the problem happens with any use of LazyColumn but if that is important let me know and I can redact the code and post them!

3

There are 3 best solutions below

3
On

In a messaging app i scroll to bottom using size of items and LazyListState

as

coroutineScope.launch {
    scrollState.animateScrollToItem(messages.size - 1)
}

and whenever user inputs a message it gets added to

 val messages = remember { mutableStateListOf<ChatMessage>() }

you can call scroll in a LaunchedEffect(messages.size){...} for it to be invoked only when recomposition happens and item count has changed

0
On

It is a very late answer, but I wrote on the LazyColumn a corroutineScope with the lazyColumnState call to scroll, my problem was on the first 10 items and I needed to stay on the first item. Maybe with this you can figure it out.

val lazyColumnListState = rememberLazyListState()
val corroutineScope = rememberCoroutineScope()

LazyColumn(
          modifier = Modifier.fillMaxWidth(),
          contentPadding = PaddingValues(vertical = 4.dp),
          state = lazyColumnListState
         ) {

            corroutineScope.launch {
                  if(itemCount == 10){
                     lazyColumnListState.scrollToItem(0)
                  }
            }

           items(
                items = ...
0
On

You can achieve that behavior by this:

   val uiState = chatViewModel.uiState.collectAsState()
   val chatListState = rememberLazyListState()

   LaunchedEffect(uiState.value.messages){
    chatListState.animateScrollToItem(chatListState.layoutInfo.totalItemsCount)
   }

        LazyColumn(
            modifier = Modifier.fillMaxSize(),
            contentPadding = PaddingValues(16.dp),
            verticalArrangement = Arrangement.spacedBy(24.dp),
            state = chatListState,
        ) {
            items(uiState.value.messages) {