ITmob-Ly
发布于 2023-04-10 / 167 阅读
0

如何不通过 Scaffold 使用 Snackbar?如何在 ModalBottomSheetLayout 中使用 Snackbar?

介绍

下面的代码是使用 Snackbar 的常用方式(和 Scaffold 一起使用),使用 ScaffoldState 提供的 SnackbarHost 来显示 Snackbar,它有默认的 Snackbar 显示位置,并且会处理页面中有 FloatingActionButtonSnackbar 的显示位置。

@Composable
fun MainScreen() {
    val scaffoldState = rememberScaffoldState()
    val coroutineScope = rememberCoroutineScope()

    Scaffold(scaffoldState = scaffoldState) {
        Button(onClick = { 
            coroutineScope.launch {
                scaffoldState.snackbarHostState.showSnackbar("Button Clicked")
            }
        }) {
            Text("Click to show Snackbar")
        }
    }
}

但是有时可能也会遇到需要在没有 Scaffold/脚手架 的布局中使用 Snackbar。

例如,想要在 ModalBottomSheetLayout 中使用 Snackbar 时,ModalBottomSheet 没有 SnackbarHost 参数,不能轻松的和 Scaffold 整合到一起使用。

这种情况不使用 Scaffold,定义我们自己的 SnackbarHostState 即可。

不通过 Scaffold 使用 Snackbar

@Composable
private fun SnackbarWithoutScaffold() {
    Box(Modifier.fillMaxSize()) {
        val snackbarHostState = remember { SnackbarHostState() }
        val coroutineScope = rememberCoroutineScope()

        Button(onClick = {
            coroutineScope.launch {
                snackbarHostState.showSnackbar("Button Clicked")
            }
        }) {
            Text("Click to show Snackbar")
        }

        SnackbarHost(
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .windowInsetsPadding(WindowInsets.safeDrawing),
            hostState = snackbarHostState,
        )
    }
}

Snackbar without Scaffold

ModalBottomSheetLayout 中使用 Snackbar

@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun ModalBottomSheetWithSnackbar() {
    val bottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
    val snackbarHostState = remember { SnackbarHostState() }
    val coroutineScope = rememberCoroutineScope()

    Box(Modifier.fillMaxSize()) {
        Button(
            onClick = {
                coroutineScope.launch {
                    bottomSheetState.show()
                }
            },
        ) {
            Text("Click to show ModalBottomSheet")
        }

        ModalBottomSheetLayout(
            sheetState = bottomSheetState,
            sheetContent = {
                Button(
                    modifier = Modifier.padding(horizontal = 16.dp, vertical = 70.dp),
                    onClick = {
                        coroutineScope.launch {
                            snackbarHostState.showSnackbar("Button Clicked")
                        }
                    },
                ) {
                    Text("Click to show Snackbar")
                }
            },
        ) {
            Text(text = "ModalBottomSheet with Snackbar")
        }

        SnackbarHost(
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .windowInsetsPadding(WindowInsets.safeDrawing),
            hostState = snackbarHostState,
        )
    }
}

Snackbar with ModalBottomSheet