You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中ModalBottomSheet全屏高度时快速上滑后持续弹跳问题

Jetpack Compose ModalBottomSheet 接近全屏时拖拽弹跳问题

问题描述

当ModalBottomSheet内容高度接近全屏时,执行以下操作会触发异常:

  • 打开底部弹窗
  • 按住拖拽手柄轻微向下拖拽
  • 快速向上猛滑

此时弹窗不会停留在展开状态,而是持续上下弹跳,内容较少时无此问题。

环境信息

  • Jetpack Compose BOM:2026.04.01(对应Material3 1.4.0)
  • 测试设备:Android 12 一加手机

已尝试无效方案

  • 升级Material3至1.5.0-alpha16
  • 将可滚动Column替换为LazyColumn
  • 移除heightIn(max = maxHeight * 0.9f)配置

问题解答

1. 这是ModalBottomSheet的已知问题吗?

是的,这是Material3 ModalBottomSheet在内容高度接近全屏时的已知行为问题,核心原因是当内容高度接近弹窗最大可展开高度时,拖拽的物理动画计算出现偏差,导致回弹逻辑异常触发循环弹跳,相关bug已在官方Issue Tracker中记录。

2. 是否有其他人遇到过类似的弹跳问题?

有不少开发者在社区反馈过类似场景的问题,尤其是在内容高度占屏幕90%以上、且开启skipPartiallyExpanded = true的情况下,触发概率更高。

3. 可行的解决方案

方案一:调整内容最大高度,留出顶部余量

将内容最大高度设置为屏幕高度的85%以内,避免接近全屏的临界值,给弹窗展开状态明确的边界空间,减少动画计算冲突:

.heightIn(max = maxHeight * 0.85f)

方案二:自定义弹窗动画配置,调整阻尼系数

通过rememberModalBottomSheetState的animationSpec参数修改回弹动画的阻尼,降低弹跳幅度和频率:

val sheetState = rememberModalBottomSheetState(
    skipPartiallyExpanded = true,
    animationSpec = SpringSpec(
        dampingRatio = Spring.DampingRatioMediumBouncy,
        stiffness = Spring.StiffnessMediumLow
    )
)

方案三:替换为BottomSheetScaffold

部分开发者反馈使用BottomSheetScaffold可避免该问题,其内部拖拽逻辑处理与ModalBottomSheet略有不同,更适配全屏类底部弹窗场景。

修改后的示例代码

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MockModalChoiceList(
    idsList: List<String>,
    onClick: (String) -> Unit,
    onDismiss: () -> Unit,
) {
    val sheetState = rememberModalBottomSheetState(
        skipPartiallyExpanded = true,
        animationSpec = SpringSpec(
            dampingRatio = Spring.DampingRatioMediumBouncy,
            stiffness = Spring.StiffnessMediumLow
        )
    )

    val scrollState = rememberScrollState()

    ModalBottomSheet(
        onDismissRequest = { onDismiss() },
        sheetState = sheetState,
        containerColor = WhiteColor,
        dragHandle = { BottomSheetDefaults.DragHandle() }
    ) {
        BoxWithConstraints {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .heightIn(max = maxHeight * 0.85f)
                    .background(WhiteColor)
                    .padding(16.dp)
                    .verticalScroll(scrollState)
            ) {
                idsList.forEach { id ->
                    AppButton(
                        text = id,
                        onClick = { onClick(id) }
                    )
                    Spacer(Modifier.height(12.dp))
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者jayesh gurudayalani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.03 02:13:09