I'm trying to add a simple animation for one scree...
# compose
c
I'm trying to add a simple animation for one screen where I want to "fake" it looking like a bottom sheet. (appears from the bottom, and exits by moving down). This code below "works" but I noticed when I slow down the animation that the screen that I'm on before this FakeModal fades to grey when transitioning instead of staying there. Am I missing something simple here? I never really used android nav transitions in view-land before so maybe I'm missing something fundamental here. Thanks!
Copy code
composable(
  Screen.FakeModal.route,
  enterTransition = {
    slideIntoContainer(AnimatedContentScope.SlideDirection.Up, animationSpec = tween(1500))
  },
  exitTransition = {
    slideOutOfContainer(AnimatedContentScope.SlideDirection.Down, animationSpec = tween(1500))
  },
👀 1
i
So what is your
exitTransition
on the screen that you are on before this screen? If you don't define one, you'll be getting the default fade
There isn't an ExitTransition.Hold that you can use directly though, see the conversation on https://issuetracker.google.com/issues/192993290
c
Interesting. I guess I will make my own ExitTransition.Hold that I apply on the "exit" of the previous screen. thanks for the pointer Ian
i
Yep, that's where using the
initialState
(the destination you're coming from) and the
targetState
(the destination you are going to) that are available via the
AnimatedContentScope
the
enterTransition
and
exitTransition
blocks have make it possible to customize the transition based on exactly what pair you are navigating between
There's some examples in the original blog post about Animations in Navigation Compose: https://medium.com/androiddevelopers/animations-in-navigation-compose-36d48870776b
As noted in that article, you could also define those animations at a higher level in your graph structure, thus ensuring that any destination that goes to your FakeModal would have the right enter/exit transition since if you return null from either lambda, it then asks the parent graph what animation it should run (that's precisely how the default animations are defined - the Animations you set on the
AnimatedNavHost
level are used for the root graph, which has the final say in the default animations)
c
Thanks yeah. I think probably what tripped me up was just forgetting that there's a default anim. And so I was super confused when my screen underneath just turned grey
If anyone else stumbles across this, this was my solution
Copy code
composable(Screen.MyScreen.route, exitTransition = {
  when (targetState.destination.route) {
    Screen.FakeBottomSheet.route -> holdOut(1500)
    else -> null // use the defaults
  }}) {
and
Copy code
fun holdOut(
  durationMillis: Int = 1500,
): ExitTransition = fadeOut(
  // TODO: Refer <https://issuetracker.google.com/issues/192993290>
  // targetAlpha = 1f,
  targetAlpha = 0.999f,
  animationSpec = tween(
    durationMillis = durationMillis,
    easing = LinearEasing
  )
)
z
@Colton Idle Does that work regardless of the EnterTransitions spec/duration? I can dig it up if needed, theres an old thread where I spoke with Doris Lou about this and how it didnt work great with spring animations. You would have to use tween for the enter as well so that the exit could match its duration.
i
This technique would require that the enter and exit match duration exactly, yes. An actual Hold instead of this hack would still be way better
c
Yeah. I'm using tween and using the same value for duration so it seems to work as I wanted.