Android Compose配置变更(如屏幕旋转)时Snackbar重复显示如何解决?
解决方案
问题原因
- 屏幕旋转属于Android配置变更,默认
remember存储的状态、ScaffoldState都会被重置,Compose触发重组后会再次执行展示Snackbar的逻辑 - 当前代码没有维护「Snackbar已展示」的标记,只要
state为true,每次重组都会触发LaunchedEffect执行
实现方案
通过rememberSaveable存储一次性展示的标记,Snackbar完成展示后标记为已消费,配置变更后不会重新触发:
@Composable fun LoginScreen( state: Boolean = true, scaffoldState: ScaffoldState = rememberScaffoldState() ) { // 用rememberSaveable存储展示标记,配置变更不会丢失 val hasShownSnackbar = rememberSaveable { mutableStateOf(false) } // 仅当有错误且未展示过Snackbar时才触发 if (state && !hasShownSnackbar.value) { LaunchedEffect(scaffoldState.snackbarHostState) { scaffoldState.snackbarHostState.showSnackbar( message = "Error message", actionLabel = "Retry message" ) // 展示完成后标记为已展示,后续所有重组都不会再触发 hasShownSnackbar.value = true } } Scaffold(scaffoldState = scaffoldState) { } }
如果错误状态来自ViewModel,更规范的实现是在ViewModel中维护一次性事件队列,Snackbar展示完成后向ViewModel发送事件将该错误标记为已消费,逻辑和上述方案一致,且可以跨越页面生命周期。
内容的提问来源于stack exchange,提问作者Nestor Perez
相关产品推荐
相关产品推荐

