I am using Jetpack Compose (version 1.1.1) and I am trying to show an snackbar-style alert coming from the top of the screen using AnimatedVisibility. However, when I do so the alert escapes its container and overlaps the content above it (in this case, the action bar). Also, the content below it (the button) waits until the animation is finished before adjusting its position. This results in a jumpy effect. I would like it to slide down in sync with the alert.
@Composable
fun HomeScreen() {
val showAlert = remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
Column(Modifier.fillMaxHeight()) {
ActionBar("Home Screen")
Column {
Alert(visible = showAlert.value)
Button(modifier = Modifier.padding(16.dp), onClick = {
scope.launch {
showAlert.value = true
delay(1000)
showAlert.value = false
}
}) {
Text("Show Alert")
}
}
}
}
@Composable
private fun ActionBar(title: String) {
TopAppBar(backgroundColor = Color.Blue, contentColor = Color.White) {
Row(verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(start = 8.dp, end = 8.dp)) {
Text(title)
}
}
}
@Composable
fun Alert(visible: Boolean) {
AnimatedVisibility(visible = visible, enter = slideInVertically(), exit = slideOutVertically()) {
Column(Modifier.fillMaxWidth().background(Color.Red)) {
Text("An error has occurred", Modifier.padding(16.dp), style = TextStyle(Color.White))
}
}
}
@Preview
@Composable
fun HomeScreenPreview() {
Box(Modifier.fillMaxSize().background(Color.White)) {
HomeScreen()
}
}
For the overlap issue, you can use the modifier:
Modifier.clipToBounds()
For the 'jumpy effect' you can put the alert text and the page content in a single column and animate the offset.
If your alert height is not fix, you can get it using the modifier
Modifier.onGloballyPositioned