Jetpack compose snackbar not displayed at bottom of screen

2.1k Views Asked by At

I tried below code and I observe snackbar is not displayed at bottom of screen. My task is to display snackbar on click of button. I wrote code related to display button in a column in function DisplaySnackBarOnClik() The code to display snackbar is written in MySnackBar(). Can anyone help me to display snackbar in the bottom of the screen by observing the below code:

@Composable 
fun DisplaySnackBarOnClik() {

    var canShowSnackBar by remember {
        mutableStateOf(false)
    }

Column(
        modifier = Modifier
            .verticalScroll(rememberScrollState())
            .fillMaxWidth(),
        verticalArrangement = Arrangement.spacedBy(5.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {


Button(
              onClick = { canShowSnackBar = ! canShowSnackBar },
              modifier = modifier,
              enabled = isEnabled,
              elevation =  ButtonDefaults.elevation(
                       defaultElevation = 10.dp,
                       pressedElevation = 15.dp,
                       disabledElevation = 0.dp
             ),
             colors = ButtonDefaults.buttonColors(
             backgroundColor = colorResource(R.color.cgux_primary_700),
             contentColor = colorResource(R.color.white)
        )
            ) {
        Text(text = "Show Snack Bar")
    }

 if (canShowSnackBar) {
            MySnackbar("Hello, Snackbar!", "Dismiss")
        }

}


@Composable fun MySnackbar(
    message: String, actionLabel: String, duration: SnackbarDuration = SnackbarDuration.Short
) {
    val snackbarHostState = remember { SnackbarHostState() }

    LaunchedEffect(snackbarHostState) {
        snackbarHostState.showSnackbar(message, actionLabel, duration = duration)
    }
    Box(
        Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter
    ) {
        SnackbarHost(
            hostState = snackbarHostState
        )
    }
}

enter image description here

2

There are 2 best solutions below

1
On

You have to wrap your contents inside Box like this. its basic structure to follow

Box {
   Column {
      Button()
    }
    MySnackbar()
}

and most important you can remove the box from your the MySnackbar composable.

Detail Answer


@Composable
fun DisplaySnackBarOnClik() {
    var canShowSnackBar by remember {
        mutableStateOf(false)
    }

    Box(
        Modifier.fillMaxSize(),
        contentAlignment = Alignment.BottomCenter,
    ) {
        Column(
            modifier = Modifier
                .verticalScroll(rememberScrollState())
                .fillMaxWidth().padding(bottom = 60.dp),
            verticalArrangement = Arrangement.spacedBy(5.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
        ) {
            Button(
                onClick = { canShowSnackBar = !canShowSnackBar },
                enabled = true,
                elevation = ButtonDefaults.elevation(
                    defaultElevation = 10.dp,
                    pressedElevation = 15.dp,
                    disabledElevation = 0.dp,
                ),
                colors = ButtonDefaults.buttonColors(
                    backgroundColor = colorResource(R.color.purple_200),
                    contentColor = colorResource(R.color.white),
                ),
            ) {
                Text(text = "Show Snack Bar")
            }
        }
        if (canShowSnackBar) {
            MySnackbar("Hello, Snackbar!", "Dismiss")
        }
    }
}

@Composable
fun MySnackbar(
    message: String,
    actionLabel: String,
    duration: SnackbarDuration = SnackbarDuration.Short,
) {
    val snackbarHostState = remember { SnackbarHostState() }

    LaunchedEffect(snackbarHostState) {
        snackbarHostState.showSnackbar(message, actionLabel, duration = duration)
    }

    SnackbarHost(
        hostState = snackbarHostState,
    )
}

enter image description here

0
On

It happens because the Box with the SnackbarHost is inside the Column with the verticalScroll.

You have to move the Box outside the scrollable column.

Column() {

    var canShowSnackBar by remember { mutableStateOf(false) }

    Column(
        modifier = Modifier
            .verticalScroll(rememberScrollState())
            .fillMaxWidth(),
        verticalArrangement = Arrangement.spacedBy(5.dp),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Button()
    }

    if (canShowSnackBar) {
        MySnackbar("Hello, Snackbar!", "Dismiss")
    }

}