DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Snackbar in Jetpack Compose: SnackbarHost, Actions & Custom Styling

Snackbar in Jetpack Compose: SnackbarHost, Actions & Custom Styling

Snackbars are lightweight feedback components in Material Design that display brief messages at the bottom of the screen. In Jetpack Compose, they're managed through SnackbarHost, SnackbarHostState, and the suspend function showSnackbar().

SnackbarHostState & showSnackbar()

The SnackbarHostState maintains the state and provides a suspend function showSnackbar() for displaying messages:

val snackbarHostState = remember { SnackbarHostState() }

LaunchedEffect(triggerEvent) {
    snackbarHostState.showSnackbar(
        message = "Action completed!",
        duration = SnackbarDuration.Short
    )
}

Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    content = { ... }
)
Enter fullscreen mode Exit fullscreen mode

Adding Actions with SnackbarResult

Handle user interaction using SnackbarResult:

LaunchedEffect(Unit) {
    val result = snackbarHostState.showSnackbar(
        message = "Item deleted",
        actionLabel = "Undo",
        duration = SnackbarDuration.Long
    )

    when (result) {
        SnackbarResult.ActionPerformed -> {
            // Undo action
            viewModel.restoreItem()
        }
        SnackbarResult.Dismissed -> {
            // User dismissed
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Duration Options

  • SnackbarDuration.Short - 4 seconds
  • SnackbarDuration.Long - 10 seconds
  • SnackbarDuration.Indefinite - Until dismissed

Custom Colors & Styling

Customize the Snackbar appearance:

SnackbarHost(
    hostState = snackbarHostState,
    modifier = Modifier.padding(8.dp),
    snackbar = { data ->
        Snackbar(
            containerColor = Color(0xFF323232),
            contentColor = Color.White,
            actionColor = Color(0xFF4CAF50),
            shape = RoundedCornerShape(8.dp),
            modifier = Modifier.padding(16.dp)
        ) {
            Text(data.visuals.message)
        }
    }
)
Enter fullscreen mode Exit fullscreen mode

ViewModel Integration via SharedFlow

For MVVM patterns, emit snackbar events from ViewModel:

class MyViewModel : ViewModel() {
    private val _snackbarEvents = MutableSharedFlow<String>()
    val snackbarEvents: SharedFlow<String> = _snackbarEvents.asSharedFlow()

    fun showSuccess() {
        viewModelScope.launch {
            _snackbarEvents.emit("Operation successful!")
        }
    }
}

// In Composable
val snackbarHostState = remember { SnackbarHostState() }
val viewModel = viewModel<MyViewModel>()

LaunchedEffect(Unit) {
    viewModel.snackbarEvents.collect { message ->
        snackbarHostState.showSnackbar(message)
    }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices

  1. Use Scaffold - Snackbar positioning handles bottom padding
  2. Suspend Safety - showSnackbar() suspends until dismissed; collect results
  3. Brief Messages - Keep under 20 characters when possible
  4. Meaningful Actions - Use action labels for undoable operations
  5. Avoid Duplicate States - Use SnackbarHostState as single source of truth

Snackbars are perfect for temporary feedback without interrupting user flow. Combine with SnackbarResult handling for complete user control.


8 Android App Templates → https://myougatheax.gumroad.com

Top comments (0)