使用 Scaffold 在 Material Design 3 中显示 Snackbar

Fan*_*dez 17 android material-components-android android-jetpack-compose

决定在我的新 Jetpack Compose 项目中尝试Material Design 3 。一切都很舒适,直到我碰壁时需要展示一个 Snackbar。

MD2中,这非常简单,您可以在使用SnackbarHostState.showSnackbar()协程作用域内的函数完成的支架中显示小吃栏。我观察到您只需要从androidx.compose.material.rememberScaffoldState材质库导入即可。

import androidx.compose.material.rememberScaffoldState


@Composable
fun MyScreenInMaterial2() {
    val scaffoldState = rememberScaffoldState()
}
Run Code Online (Sandbox Code Playgroud)

当我在MD3中尝试相同的操作时,该rememberScaffoldState()功能未得到解析。 在此输入图像描述

对于那些深入了解 MD3 世界的人来说,如何在脚手架中显示 Snackbar?我已经检查了文档和在线资源,但没有找到解决方案。

Dam*_*tla 28

这里有一个来自官方文档的示例。

val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                // show snackbar as a suspend function
                scope.launch {
                    snackbarHostState.showSnackbar(
                        "Snackbar # ${++clickCount}"
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Body content",
            modifier = Modifier.padding(innerPadding).fillMaxSize().wrapContentSize()
        )
    }
)
Run Code Online (Sandbox Code Playgroud)

  • 天哪,我怎么错过了这个。**MDC3** 消除了“scaffoldState”参数,您可以在 MD2 上使用该参数,如下所示:“scaffoldState.snackbarHostState.showSnackbar()”。您现在需要 _remember { SnackbarHostState() }_ 您可以像 `snackbarHostState.showSnackbar()` 一样使用它。因此,MD3 上不再需要 **ScaffoldState**!谢谢@达米安 (5认同)

Joa*_*huk 6

听听达米安·佩特拉(Damian Petla)的回答

如果你使用 aCoroutineScope那么你会收到一条警告说CoroutineCreationDuringComposition

官方文档建议使用LaunchedEffect替代方法来避免这种副作用。

所以建议的代码如下所示:

val snackbarHostState = remember { SnackbarHostState() }

Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    floatingActionButton = {
        var clickCount by remember { mutableStateOf(0) }
        ExtendedFloatingActionButton(
            onClick = {
                LaunchedEffect(snackbarHostState) {
                    snackbarHostState.showSnackbar(
                        "Snackbar # ${++clickCount}"
                    )
                }
            }
        ) { Text("Show snackbar") }
    },
    content = { innerPadding ->
        Text(
            text = "Body content",
            modifier = Modifier.padding(innerPadding).fillMaxSize().wrapContentSize()
        )
    }
)
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的 n 文档支持它,感谢您的见解 (2认同)