Jetpack Compose:返回导航时ModalBottomSheetLayout闪烁问题求助
解决ModalBottomSheetLayout返回时闪烁问题
核心原因
导航到第二页时,包含底部模态的页面会从Compose组合树中移除,返回时重新组合。若用普通remember管理sheetState,状态会被重置,导致重新执行展开动画,出现闪烁。
解决方案
1. 使用rememberSaveable持久化状态
ModalBottomSheetState无法直接被rememberSaveable序列化,需借助其自带的Saver保存状态,确保导航返回时状态不丢失:
import androidx.compose.material.ModalBottomSheetLayout import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.SwipeableDefaults // 在Compose页面内 val sheetState = rememberSaveable( saver = ModalBottomSheetState.Saver( animationSpec = SwipeableDefaults.AnimationSpec ) ) { // 初始设置为展开状态 ModalBottomSheetState(ModalBottomSheetValue.Expanded) } ModalBottomSheetLayout( sheetState = sheetState, sheetContent = { // 条目列表,点击导航至下一页 Column { TextButton(onClick = { navController.navigate("second_page") }) { Text("跳转至第二页") } // 其他条目... } } ) { // 页面主内容 }
2. 将状态托管至ViewModel
利用ViewModel的生命周期独立性(导航过程中不会被销毁),把sheetState放在ViewModel中,确保状态在页面切换时持续保留:
// ViewModel类 import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.ModalBottomSheetValue import androidx.lifecycle.ViewModel class SheetViewModel : ViewModel() { // 初始化时设置为展开状态 val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Expanded) } // Compose页面内 import androidx.lifecycle.viewmodel.compose.viewModel val viewModel: SheetViewModel = viewModel() ModalBottomSheetLayout( sheetState = viewModel.sheetState, sheetContent = { TextButton(onClick = { navController.navigate("second_page") }) { Text("跳转至第二页") } } ) { // 主内容 }
3. 避免导航时修改Sheet状态
点击条目导航时,不要调用sheetState.hide()或其他修改状态的方法,保持Sheet处于展开状态。返回时状态未发生变化,就不会触发额外动画。
注意事项
- 使用
rememberSaveable时,需确保与状态相关的参数(如动画Spec)在保存和恢复时一致。 - 使用ViewModel时,需确保ViewModel的作用域正确(如与导航宿主绑定),避免多个页面共享同一状态导致异常。
内容的提问来源于stack exchange,提问作者Shivani Verma
相关产品推荐
相关产品推荐

