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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 10:57:03