如何让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
相关产品推荐
相关产品推荐

