android 喷气背包组成:滚动到底部收听者(列表结束)

taor4pac  于 2023-01-19  发布在  Android
关注(0)|答案(6)|浏览(126)

我想知道当到达列表底部时是否可以将observer放入@Compose函数中(类似于recyclerView.canScrollVertically(1)
先谢了。

rwqw0loc

rwqw0loc1#

可以使用rememberLazyListState()并比较

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

如何使用示例

首先添加上述命令作为扩展名(例如,extensions.kt文件):

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

然后在下面的代码中使用它:

@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
  }
}
xpcnnkqh

xpcnnkqh2#

对我来说,最好也是最简单的解决方案是添加LaunchedEffect作为LazyColumn中的最后一项:

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

gab6jxml3#

基于另一个答案,我认为recyclerView.canScrollVertically(1)涉及底部滚动的最佳解释是

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

xe55xuns4#

只需使用firstVisibleItemIndex并将其与上一个索引进行比较。如果匹配,则您位于末尾,否则不位于末尾。将其用作lazyListState.firstVisibleItemIndex

uz75evzq

uz75evzq5#

找到了一个比其他答案简单得多的解决方案。获取list的最后一项索引。在lazyColumn的itemsIndexed内部将其与lastIndex进行比较。当到达list末尾时,它将触发if语句。代码示例:

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

zqry0prt6#

1.4.0-alpha03开始,您可以使用**LazyListState#canScrollForward**检查您是否位于列表末尾。
比如:

val state = rememberLazyListState()
val isAtBottom = !state.canScrollForward

LaunchedEffect(isAtBottom){
    if (isAtBottom) doSomething()
}

在此版本之前,您可以使用包含可见项信息的**LazyListState#layoutInfo**。请注意,您应该使用derivedStateOf以避免重复的重新组合。
使用一些东西:

@Composable
private fun LazyListState.isAtBottom(): Boolean {

    return remember(this) {
        derivedStateOf {
            val visibleItemsInfo = layoutInfo.visibleItemsInfo
            if (layoutInfo.totalItemsCount == 0) {
                false
            } else {
                val lastVisibleItem = visibleItemsInfo.last()
                val viewportHeight = layoutInfo.viewportEndOffset + layoutInfo.viewportStartOffset

                (lastVisibleItem.index + 1 == layoutInfo.totalItemsCount &&
                        lastVisibleItem.offset + lastVisibleItem.size <= viewportHeight)
            }
        }
    }.value
}

上面的代码不仅检查列表中的最后一个visibile item == last index,还检查它是否完全可见(lastVisibleItem.offset + lastVisibleItem.size <= viewportHeight)。
然后:

val state = rememberLazyListState()
var isAtBottom = state.isAtBottom()
LaunchedEffect(isAtBottom){
    if (isAtBottom) doSomething()
}

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

相关问题