1

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:

example GIF

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?

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.