20. Sep 2021Android

Jetpack Compose Basics - Learn how to use Snackbar properly

Snackbar is UI component that provides brief message at the bottom of the screen. It is used to inform users that app has performed action or will perform action. Only one snackbar can be used at a time and has to contain only single action which is optional.

Peter ŠulyAndroid developer

This simple component consist of message (1), container (2) and optional action button (3). Message can be maximally 2 lines long.

Example of snackbar usage
Example of snackbar usage

Snackbar in Jetpack Compose

Snackbar

In Jetpack Compose there is composable function named Snackbar. It's just visual representation of snackbar as defined in Material design guidelines, without show or hide options and without animations. Usually you will need to use SnackbarHost.

SnackbarHost

This component is responsible for showing(or hiding snackbar after defined time) and it's fade animations. Simply said, SnackbarHost is wrapper of Snackbar mentioned above. It takes 3 parameters

  • modifier - used for changes from the caller side
  • snackbar - composable function that obtains SnackbarData, defaultly just Snackbar composable. If you are curious, SnackbarData is interface consisting of message, action label and duration of snackbar
  • hostState - this parameter is covered below
@Composable
fun SnackbarHost(
    hostState: SnackbarHostState,
    modifier: Modifier = Modifier,
    snackbar: @Composable (SnackbarData) -> Unit = { Snackbar(it) }
)

SnackbarHostState

As descriptive name of class suggest, it is used to control state of SnackbarHost. As Material design guideline mentions, only one snackbar should be showed at a time, others are queued and will show later by SnackbarHostState.

Only mandatory parameter of SnackbarHostState is hostState that can be obtained simply by it's constructor. Then you can just place SnackbarHost wherever you want. But snackbar still doesn't show, so how to do that?

val snackbarHostState = remember { SnackbarHostState() }
.
.
.
SnackbarHost(hostState = snackbarHostState)

 

How to show snackbar in Jetpack Compose?

Snackbar is showed as reaction on something. In our case "something" is click on button. ShowSnackbar is suspend function thus coroutine scope is needed. You need to remember coroutine scope outside of onClick function because when the scope is cancelled the snackbar is removed from the queue.

@Composable
fun SnackbarScreen() {
    val scope = rememberCoroutineScope()
    val snackbarHostState = remember { SnackbarHostState() }
    .
    .
    .
    FloatingActionButton(
        onClick = {
	    //Important part here
            scope.launch {
                snackbarHostState.showSnackbar("Hello there")
            }
	    //
        },
        content = { Icon(imageVector = Icons.Default.Add, contentDescription = "") }
    )
	
    SnackbarHost(hostState = snackbarHostState)
}

Custom snackbar in Jetpack Compose

Key here is to modify snackbar parameter of SnackbarHost. Without our modification default Snackbar composable is used. With code below, our design of snackbar is used but default behavior of snackbar is retained.

SnackbarHost(
    modifier = Modifier.align(Alignment.BottomCenter),
    hostState = snackbarHostState,
    snackbar = { snackbarData: SnackbarData ->
        Card(
            shape = RoundedCornerShape(8.dp),
            border = BorderStroke(2.dp, Color.White),
            modifier = Modifier
                .padding(16.dp)
                .wrapContentSize()
        ) {
            Column(
                modifier = Modifier.padding(8.dp),
                verticalArrangement = Arrangement.spacedBy(4.dp),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Icon(imageVector = Icons.Default.Notifications, contentDescription = "")
                Text(text = snackbarData.message)
            }
        }
    }
)

 

Custom snackbar from example above

More articles from the Jetpack Compose Basics series:

Peter ŠulyAndroid developer