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

如何让ModalBottomSheetLayout的sheetContent使用最新状态

问题原因

ModalBottomSheetLayout 的 sheetContent 代码块仅会在组件首次初始化时执行1次,后续弹窗的隐藏、显示操作不会触发该代码块重组,所以写在内部的 Date().toString() 只会在首次生成时间戳,后续打开弹窗都不会重新计算最新值。

修复方案

推荐两种可行的修改方式,第一种逻辑更直观易维护:

方案1:触发弹窗显示时同步更新时间戳

将时间戳定义为顶层可观察状态,点击悬浮按钮弹出弹窗之前,先更新时间戳的值,再触发弹窗显示:

class MainActivity : ComponentActivity() {
    @ExperimentalMaterialApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            AskQuestionTheme {
                val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
                val scope = rememberCoroutineScope()
                // 定义可观察的时间戳状态
                var timestamp by remember { mutableStateOf("") }

                Scaffold(
                    floatingActionButton = {
                        FloatingActionButton(
                            onClick = { 
                                // 弹出前先更新为最新时间
                                timestamp = Date().toString()
                                scope.launch { modalBottomSheetState.show() } 
                            }) {
                            Icon(Icons.Rounded.Add, contentDescription = "add")
                        }
                    }) {
                    ModalBottomSheetLayout(
                        sheetState = modalBottomSheetState,
                        sheetContent = {
                            MySheet(
                                str = timestamp,
                                onSave = { scope.launch { modalBottomSheetState.hide() } },
                                onCancel = { scope.launch { modalBottomSheetState.hide() } }
                            )
                        }
                    ) {
                        Text("hello")
                    }
                }
            }
        }
    }
}

// MySheet 代码无需修改
@Composable
fun MySheet(str: String, onSave: () -> Unit, onCancel: () -> Unit) {
    Column {
        Box(modifier = Modifier.fillMaxWidth()) {
            Icon(
                Icons.Rounded.Close,
                contentDescription = "edit",
                modifier = Modifier.align(Alignment.CenterStart).clickable { onCancel() }
            )
            Button(onClick = onSave, modifier = Modifier.align(Alignment.CenterEnd)) {
                Text("save")
            }
        }
        Text(str)
        Spacer(Modifier.height(100.dp))
    }
}

方案2:监听弹窗可见状态自动更新

如果希望时间戳更新逻辑和弹窗触发逻辑解耦,可以在sheetContent中监听弹窗的可见状态,每次弹窗变为可见时自动更新时间戳:

sheetContent = {
    var t by remember { mutableStateOf(Date().toString()) }
    // 监听弹窗可见状态,可见时更新时间
    LaunchedEffect(modalBottomSheetState.isVisible) {
        if (modalBottomSheetState.isVisible) {
            t = Date().toString()
        }
    }
    MySheet(
        str = t,
        onSave = { scope.launch { modalBottomSheetState.hide() } },
        onCancel = { scope.launch { modalBottomSheetState.hide() } }
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:06:03