'jetpack compose: scroll to bottom listener (end of list)

I am wondering if it is possible to get observer inside a @Compose function when the bottom of the list is reached (similar to recyclerView.canScrollVertically(1))

Thanks in advance.



Solution 1:[1]

you can use rememberLazyListState() and compare

scrollState.layoutInfo.visibleItemsInfo.lastOrNull()?.index == scrollState.layoutInfo.totalItemsCount - 1

How to use example:

First add the above command as an extension (e.g., extensions.kt file):

fun LazyListState.isScrolledToEnd() = layoutInfo.visibleItemsInfo.lastOrNull()?.index == layoutInfo.totalItemsCount - 1

Then use it in the following code:

@Compose
fun PostsList() {
  val scrollState = rememberLazyListState()

  LazyColumn(
    state = scrollState,),
  ) {
     ...
  }

  // observer when reached end of list
  val endOfListReached by remember {
    derivedStateOf {
      scrollState.isScrolledToEnd()
    }
  }

  // act when end of list reached
  LaunchedEffect(endOfListReached) {
    // do your stuff
  }
}

Solution 2:[2]

I think, based on the other answer, that the best interpretation of recyclerView.canScrollVertically(1) referred to bottom scrolling is

fun LazyListState.isScrolledToTheEnd() : Boolean {
    val lastItem = layoutInfo.visibleItemsInfo.lastOrNull()
    return lastItem == null || lastItem.size + lastItem.offset <= layoutInfo.viewportEndOffset
}

Solution 3:[3]

For me the best and the simplest solution was to add LaunchedEffect as the last item in my LazyColumn:

LazyColumn(modifier = Modifier.fillMaxSize()) {
    items(someItemList) { item ->
        MyItem(item = item)
    }
    item {
        LaunchedEffect(true) {
            //Do something when List end has been reached
        }
    }
}

Solution 4:[4]

Simply use the firstVisibleItemIndex and compare it to your last index. If it matches, you're at the end, else not. Use it as lazyListState.firstVisibleItemIndex

Solution 5:[5]

Found a much simplier solution than other answers. Get the last item index of list. Inside itemsIndexed of lazyColumn compare it to lastIndex. When the end of list is reached it triggers if statement. Code example:

LazyColumn(
        modifier = Modifier
            .fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        itemsIndexed(events) { i, event  ->
            if (lastIndex == i) {
                Log.e("console log", "end of list reached $lastIndex")
            }
        }
     }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 AbdulMomen عبدالمؤمن
Solution 2 DogeWeb
Solution 3 Arkadiusz M?dry
Solution 4 Richard Onslow Roper
Solution 5 FireTr3e