如何在 Jetpack Compose 的 LazyColumn/LazyRow 中禁用和启用滚动?

时间:2021-03-06 03:33:27

标签: android kotlin android-jetpack-compose

我想在 LazyColumn 中以编程方式动态启用和禁用滚动。

LazyListState 上似乎没有任何相关函数或 LazyColumn 本身上的相关参数。如何在 Compose 中实现这一目标?

1 个答案:

答案 0 :(得分:6)

(目前)没有内置的方法来做到这一点,这是一个合理的功能请求。

不过,scroll API 足够灵活,我们可以自行添加。基本上,我们在 MutatePriority.PreventUserInput 创建一个永无止境的假滚动来防止滚动,然后使用相同优先级的无操作滚动来取消第一次“滚动”并重新启用滚动。

以下是 LazyListState 上用于禁用/重新启用滚动的两个实用程序函数,以及它们的运行演示(需要进行一些导入,但 Android Studio 应该会为您推荐它们)。

请注意,由于我们正在控制滚动来执行此操作,因此调用 reenableScrolling 还将取消任何正在进行的滚动或甩动(也就是说,您应该仅在禁用滚动且您想重新启用它,而不仅仅是确认它已启用)。

fun LazyListState.disableScrolling(scope: CoroutineScope) {
    scope.launch {
        scroll(scrollPriority = MutatePriority.PreventUserInput) {
            // Await indefinitely, blocking scrolls
            awaitCancellation()
        }
    }
}

fun LazyListState.reenableScrolling(scope: CoroutineScope) {
    scope.launch {
        scroll(scrollPriority = MutatePriority.PreventUserInput) {
            // Do nothing, just cancel the previous indefinite "scroll"
        }
    }
}

@Composable
fun StopScrollDemo() {
    val scope = rememberCoroutineScope()
    val state = rememberLazyListState()
    Column {
        Row {
            Button(onClick = { state.disableScrolling(scope) }) { Text("Disable") }
            Button(onClick = { state.reenableScrolling(scope) }) { Text("Re-enable") }
        }
        LazyColumn(Modifier.fillMaxWidth(), state = state) {
            items((1..100).toList()) {
                Text("$it", fontSize = 24.sp)
            }
        }
    }
}