Snackbar 未在材质 3 中显示

问题描述 投票:0回答:3

我正在尝试material3,但无法显示我的snackbar。这段代码在material2中有效。当调用小吃栏时,该列会像我预期的那样向下移动,但它非常简短,比短期小吃栏短得多,并且没有任何消息。

@Composable
fun Snackbar(snackbarHostState: SnackbarHostState) {
    SnackbarHost(
        hostState = snackbarHostState,
        snackbar = { snackbarData: SnackbarData ->
            Card(
                shape = RoundedCornerShape(10.dp),
                modifier = Modifier
                    .padding(20.dp)
                    .wrapContentSize()
            ) {

                Text(text = snackbarData.visuals.message, fontSize = 30.sp)

            }
        }
    )
}
@Composable
fun LaunchSnackbar (snackbarHostState: SnackbarHostState, message: String) {
    LaunchedEffect(true) {
        snackbarHostState.showSnackbar(message = message)
    }
}
val snackbarHostState = remember { SnackbarHostState() }
Snackbar(snackbarHostState)
LaunchSnackbar(snackbarHostState = snackbarHostState, message = "Incorrect")

看起来我唯一需要改变的是

snackbarData.message  
snackbarData.visual.message 

不知道还有什么问题。

kotlin android-jetpack-compose android-jetpack-compose-material3
3个回答
1
投票

请分享您的

Scaffold
的代码。我想看看你如何将
SnackBarHost
放在
Scaffold
中。 如果您查看文档,我们会看到:

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()

Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    content = {
        …
        scope.launch {
            snackbarHostState.showSnackbar(…)
        }
    }
)

这告诉我,从下面的两行(来自您发布的代码)

Snackbar(snackbarHostState)
LaunchSnackbar(snackbarHostState = snackbarHostState, message = "Incorrect")

我们应该将第一行替换为

Scaffold
,您应该将
Snackbar(snackbarHostState)
传递给该行。 因此,如果我重复文档代码,它将看起来像:

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()

Scaffold(
    snackbarHost = { Snackbar(snackbarHostState) },
    content = {
        …
        scope.launch {
            snackbarHostState.showSnackbar(…)
        }
    }
)
LaunchSnackbar(snackbarHostState = snackbarHostState, message = "Incorrect")

0
投票

我也遇到过类似的问题,协程在重组时被取消,而小吃店的消失速度比指定的持续时间要快。我发现有效的解决方案是在 NavHost 周围创建一个脚手架,并将 SnackbarHost 分配给这个脚手架,在这个可组合项中执行启动的效果。

我还遇到的一个问题是忘记,如果您的小吃栏消息状态相同(如在同一条消息中),则 LaunchedEffect 将不会执行,因为从技术上讲您的消息状态没有改变。要以简单的方式解决此问题,请将消息类型修改为数据类,该数据类具有消息发送到消息共享流上的时间时间戳。

 @Composable
 fun NavHostComposable(
      viewModel: ViewModel
 ) {
     val navController = rememberNavController()

     val snackbarHostState = remember{SnackbarHostState()}
     val snackbarMessages by viewModel.snackbarMessages.collectAsState(initial = null)

     LaunchedEffect(key1 = snackbarMessages) {
         snackbarMessages?.let { snackBarMessage ->
              //Show snackbar message on every non-null value
              snackbarHostState.showSnackbar(
                 message = snackBarMessage.message,
                 duration = SnackbarDuration.Short
              )
          }
     }
     Scaffold(
         snackbarHost = { SnackbarHost(snackbarHostState) },
     ) { innerPadding ->
         NavHost(
            modifier = Modifier.padding(innerPadding ),
            navController = navController,
            ...
         ) {

    ...

         }
     }
}

0
投票

接受的答案中的代码有效,但显示 linter 错误 CoroutineCreationDuringComposition,“调用启动应该发生在 LaunchedEffect 内部,而不是组合内部”。

LaunchedEffect 文档位于 https://developer.android.com/jetpack/compose/side-effects#launchedeffect 显示的代码略有不同,linter 也将其评估为正确,`

// If the UI state contains an error, show snackbar
if (state.hasError) {

    // `LaunchedEffect` will cancel and re-launch if
    // `scaffoldState.snackbarHostState` changes
    LaunchedEffect(snackbarHostState) {
        // Show snackbar using a coroutine, when the coroutine is cancelled the
        // snackbar will automatically dismiss. This coroutine will cancel whenever
        // `state.hasError` is false, and only start when `state.hasError` is true
        // (due to the above if-check), or if `scaffoldState.snackbarHostState` changes.
        snackbarHostState.showSnackbar(
            message = "Error message",
            actionLabel = "Retry message"
        )
    }
}

Scaffold(
    snackbarHost = {
        SnackbarHost(hostState = snackbarHostState)
    }
) { contentPadding ->
    // ...
}`
© www.soinside.com 2019 - 2024. All rights reserved.