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

为何在LaunchedEffect中调用requireOffset仍导致应用崩溃?

解决Material3 BottomSheetScaffold实时编辑崩溃问题(获取滑动进度场景)

问题背景

在Material3的BottomSheetScaffold中,原Material版本的progress参数已被移除,于是通过requireOffset()方法获取偏移量来计算滑动进度值。但开启Android Studio实时编辑功能后,只要修改任意代码,应用就会崩溃,报错信息为尝试在初始化前获取偏移量。

问题原因

实时编辑触发Composable重组时,LaunchedEffect会在BottomSheet状态还未完全初始化的阶段就调用requireOffset(),而此时系统还未给BottomSheet分配有效偏移量,直接调用非空的requireOffset()就会抛出异常。另外初始用-1f标记初始偏移量的逻辑,在重组时可能重复执行,也会引发计算异常。

解决方案

  • 使用可空的offset替代requireOffset():offset是BottomSheetState的可空属性,未初始化时返回null,不会直接崩溃;
  • 用derivedStateOf计算进度:基于BottomSheet的偏移量、peek高度和最大高度,通过derivedStateOf自动推导进度值,减少不必要的状态更新;
  • 直接基于已知高度计算进度:不再依赖首次偏移量初始化,改用peek高度和BottomSheet的最大展开高度作为计算基准,逻辑更稳定。

修改后的代码

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PlayerViewBottomSheet(modifier: Modifier = Modifier) {
    val bottomSheetScaffoldState = rememberBottomSheetScaffoldState()
    val sheetState = bottomSheetScaffoldState.bottomSheetState
    val peekHeight = 70.dp
    val peekHeightPx = with(LocalDensity.current) { peekHeight.toPx() }

    // 计算滑动进度:0对应peek状态,1对应完全展开状态
    val progress = remember(sheetState) {
        derivedStateOf {
            val currentOffset = sheetState.offset ?: return@derivedStateOf 0f
            val maxOffset = sheetState.maxValue - peekHeightPx
            // 进度值范围:0(收起)→1(完全展开)
            (maxOffset + currentOffset) / maxOffset
        }
    }

    BottomSheetScaffold(
        sheetPeekHeight = peekHeight,
        scaffoldState = bottomSheetScaffoldState,
        sheetDragHandle = null,
        sheetShadowElevation = 1.dp,
        sheetShape = RectangleShape,
        sheetContent = {
            BottomSheetContent(
                targetValue = sheetState.targetValue,
                currentValue = sheetState.currentValue,
                progress = progress.value
            )
        }
    ) {
        MainScreen()
    }
}

额外说明

  • derivedStateOf会自动感知依赖的sheetState.offset变化,只有当偏移量改变时才重新计算进度,避免无效重组;
  • 进度计算逻辑中,maxOffset是BottomSheet从peek状态到完全展开状态的总偏移距离,通过currentOffset与maxOffset的比值得到0-1之间的进度值;
  • 移除了不必要的Experimental注解,只保留Material3相关的ExperimentalMaterial3Api即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:07:15