What I'm trying to do:
I'm using AnimatedVisibility to add an additional slideOutVertically exit animation to a single red Box in Screen1
, ontop of the default fadeOut exit animation of the NavHost which is applied to the whole screen.
What is happening:
The boolean visibleBox1
defaults to true
and controls the visiiblity of the Box. A button click sets visibleBox1
to false
and navigates to Screen2
. This works as intended, but when popBackStack()
is executed too fast from Screen2
, the Box on Screen1
isn't restored, it stays invisible:
Reason:
When navigating to Screen2
, visibleBox1
is set to false and Screen1
starts the NavHost's exit animation.
Before that is finished, Screen2
has already become visible and the button triggering popBackStack()
can be pressed. This resets the exit navigation of Screen1
, but it doesn't reset the additional animation of the Box and that stays invisible, with visibleBox1
still set to false.
Here is my code:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
val navController = rememberNavController()
NavHost(
modifier = Modifier,
navController = navController,
startDestination = "Screen1"
) {
composable("Screen1")
{
Screen1(navController)
}
composable("Screen2")
{
Screen2(navController)
}
}
}
}
@Composable
fun Screen1(navController: NavController) {
val lifecycleOwner = LocalLifecycleOwner.current
LaunchedEffect(Unit) {
Log.i("Screen1", "Created")
}
DisposableEffect(lifecycleOwner) {
onDispose {
Log.i("Screen1", "OnDispose")
}
}
var visibleBox1 by remember { mutableStateOf(true) }
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
)
AnimatedVisibility(visible = visibleBox1, exit = slideOutVertically()) {
Box(
modifier = Modifier
.height(100.dp)
.fillMaxWidth()
.background(color = Color.Red)
) {
}
}
Button(onClick = {
visibleBox1 = false
Log.i("Screen1_Button", "OnClick,navigate to Screen2")
navController.navigate("Screen2")
}) {
Text("navigate to Screen2")
}
}
}
@Composable
fun Screen2(navController: NavController) {
LaunchedEffect(Unit) {
Log.i("Screen2", "Created")
}
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("I'm Screen2")
Button(onClick = {
navController.popBackStack()
Log.i("Screen2_Button", "Onclick,popBackStack()")
}) {
Text("pop back stack")
}
}
}
}
What can I do in this case to also restore the Box?