Search code examples
androidandroid-jetpack-composesnackbarandroid-jetpack-compose-material3material3

How to show snackbar in Jetpack Compose material 3


I started to learn Jetpack Compose and it looks confusing how to implement a simple snackbar, using material3 dependencies.

Documentation shows I need a scaffold and it needs a content with padding (?). Do I need put my screen composable inside scaffolds lambda? How do I pass my message text to Snackbar? I have a simple flow collector for event from viewmodel where I want to pass the error text to snackbar.

Test()
LaunchedEffect(Unit) {
    viewModel.loginEvent.collect {
        when (it) {
            is LoginViewModel.LoginEvent.Error -> {
             // show snackbar with it.error
            }
       
            is LoginViewModel.LoginEvent.Success -> {
              // 
            }
        }
    }
}
@Composable
fun Test() {
    Box(modifier = Modifier.fillMaxSize()) {
//my composable screen
}

Solution

  • You can use a scaffoldHostState to show a snackbar inside a scaffold and yes, you should use the scaffoldPadding for the padding of e.g. a topAppBar, navigationBar ...

    Can you try this?

    @OptIn(ExperimentalMaterial3Api::class)
    @Composable
    fun Screen() {
        val snackbarHostState = remember { SnackbarHostState() }
    
        val localCoroutineScope = rememberCoroutineScope()
    
        LaunchedEffect(Unit) {
            viewModel.loginEvent.collect {
                when (it) {
                    is LoginViewModel.LoginEvent.Error -> {
                        // show snackbar with it.error
                        localCoroutineScope.launch {
                            snackbarHostState.showSnackbar(
                                message = "Error message"
                            )
                        }
                    }
                    // ...
                }
            }
        }
    
        Scaffold(
            snackbarHost = { SnackbarHost(snackbarHostState) }
        ) { scaffoldPadding ->
            Box(
                modifier = Modifier
                    .padding(scaffoldPadding)
                    .fillMaxSize()
            ) {
                // your composables ...
            }
        }
    }