Jetpack Compose:如何监听列滚动到末尾?

7

我有一个包含多个视图元素的组合列。我想检测用户何时垂直滚动该列并到达其末尾。我们该如何做到这一点?

3个回答

8
在Compose中,您应该对状态变化做出反应,而不是寻找或创建监听器。
为了防止冗余的重新组合,在这种情况下应该使用{{link1:derivedStateOf}}:只有当基于其他状态变量(如scrollState)产生的结果发生变化时,它才会触发重新组合:
val scrollState = rememberScrollState()
val endReached by remember {
    derivedStateOf {
        scrollState.value == scrollState.maxValue
    }
}

如果你需要在改变变量时执行一些副作用,比如请求更多数据,你可以根据副作用文档中的不同方法在Compose中实现。例如,使用LaunchedEffect

if (endReached) {
    LaunchedEffect(Unit) {
        // react on scroll end
    }
}

3
你可以使用scrollState.value和scrollState.maxValue来检查它。
val scrollState = rememberScrollState()

Log.i("ScrollValue", "current: ${scrollState.value}, max: ${scrollState.maxValue}")
if (scrollState.value == scrollState.maxValue) {
    // End
}

Column(
    modifier = Modifier
        .fillMaxSize()
        .verticalScroll(scrollState)
) {...}

1
@Composable
fun LazyListState.OnBottomReached(
    loadMore : () -> Unit
){
    val shouldLoadMore = remember {
        derivedStateOf {
            val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull()
                ?: return@derivedStateOf true
          
            lastVisibleItem.index == layoutInfo.totalItemsCount - 1
        }
    }
    
    // Convert the state into a cold flow and collect
    LaunchedEffect(shouldLoadMore){
        snapshotFlow { shouldLoadMore.value }
            .collect { 
                // if should load more, then invoke loadMore
                if (it) loadMore()
        }
    }
}

你要找的部分应该是“derivedStateOf”。
这位作者写了一篇关于此的文章:https://manavtamboli.medium.com/infinite-list-paged-list-in-jetpack-compose-b10fc7e74768

它多次调用了loadMore函数。有没有办法确保它只被调用一次? - Bugs Happen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接