当创建带有嵌套 LazyColumn 的 BottomSheet 时,我得到了不可预测的滚动结果。当滚动到列表底部,然后向后退一点时,有时它会开始关闭 BottomSheet,而不是继续滚动到 LazyColumn 的顶部。
如何确保 BottomSheet 仅在 LazyColumn 位于顶部位置时才开始关闭?
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NestedScrollBottomSheet(
content: @Composable () -> Unit,
) {
val scaffoldState = rememberBottomSheetScaffoldState()
val numbers = remember { (1 .. 100).toList() }
BottomSheetScaffold(
scaffoldState = scaffoldState,
sheetShape = RoundedCornerShape(
0.dp,
),
sheetPeekHeight = 94.dp,
sheetDragHandle = {},
sheetContent = {
Box(
modifier = Modifier
.fillMaxWidth()
.offset(y = 1.dp)
.border(
1.dp,
MainBorderBase,
shape = RoundedCornerShape(
topStart = 12.dp,
topEnd = 12.dp,
bottomEnd = 0.dp,
bottomStart = 0.dp
)
)
) {
LazyColumn {
items(numbers) { number ->
Row(
modifier = Modifier
.fillMaxWidth()
.height(40.dp)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
"$number",
color = Color.White
)
}
}
}
}
},
content = {
content()
}
)
}
您可以使用
LazyColumn
确定 lazyListState
是否位于顶部。基于此,sheetSwipeEnabled
将被设置为isAtTop.value
。
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NestedScrollBottomSheet(
content: @Composable () -> Unit,
) {
val scaffoldState = rememberBottomSheetScaffoldState()
val numbers = remember { (1..100).toList() }
val lazyListState = rememberLazyListState()
val isAtTop =
remember { derivedStateOf { lazyListState.firstVisibleItemIndex == 0 && lazyListState.firstVisibleItemScrollOffset == 0 } }
BottomSheetScaffold(
scaffoldState = scaffoldState,
sheetShape = RoundedCornerShape(0.dp),
sheetPeekHeight = 94.dp,
sheetDragHandle = {},
sheetSwipeEnabled = isAtTop.value,
sheetContent = {
Box(
modifier = Modifier
.fillMaxWidth()
.offset(y = 1.dp)
.border(
1.dp,
MainBorderBase,
shape = RoundedCornerShape(
topStart = 12.dp,
topEnd = 12.dp,
bottomEnd = 0.dp,
bottomStart = 0.dp
)
)
) {
LazyColumn(
state = lazyListState,
) {
items(numbers) { number ->
Row(
modifier = Modifier
.fillMaxWidth()
.height(40.dp)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
"$number",
color = Color.White
)
}
}
}
}
},
content = {
content()
}
)
}