I am doing the custom animations for enter/exit an...
# compose
p
I am doing the custom animations for enter/exit an item in Composable. For enter animation I am running the anim from
onPlaced
lambda. That way every time my view appears on the screen it animates nicely. Now, I need to make exit animation, but I believe there is no modifier that I could use for it, right? The only think that comes to my mind is DisposableEffect that will run when child view exit the composition.
d
Are you hoping to get the signal to start animating out, or acquire the target size/position for the exit animation from a modifier?
p
Signal to start animating out. I got that signal from onDispose but it is to late to fire the animation. onDispose is called when view is no longer visible. Basically i want to have the same effect as animated Visibility compostable but without wrapping the view in another component and simple do not care about the state. If visible, animate in, if not visible animate out
d
Yea, onDispose would be too late, unless you cache the drawing of the removed item and render it from a different (e.g. parent layout's)
DrawScope
on its way out.
p
this is the modifier that works nice for item placement:
Copy code
fun Modifier.animatePlacement(
    durationMillis: Int = 200,
    easing: Easing = EaseOutBack,
    offsetPercent: Float = 0.5f,
): Modifier = composed {
    val scope = rememberCoroutineScope()
    val anim = remember { Animatable(1f) }
    var dimension by remember { mutableStateOf(0) }

    this
        .onPlaced {
            dimension = (it.size.height * offsetPercent).toInt()
            if (anim.value == 1f) {
                scope.launch {
                    anim.animateTo(
                        targetValue = 0f,
                        animationSpec = tween(durationMillis, easing = easing)
                    )
                }
            }
        }
        .offset {
                IntOffset(
                    x = 0,
                    y = (dimension * anim.value).toInt()
                )
            }
        .alpha(1f - anim.value)
}
Caching feels like overenginiring. We will use that to a lot of different composables. It might be a text, button, image, or the whole column with video, images, etc so ideally I would like to have something like:
Copy code
.onRemove {
scope.launch {
    anim.animateTo(targetValue = 1f, animSpec = tween(durationMillis, easing = easing))
} 
}
d
Agreed that caching would introduce more work, although that's the easiest way to retain the already removed content. Curious if you have videos/button etc in the removed content, do you expect the video to continue to play and button ripple animation to continue to run while animating out?
p
Could you send me a snippet of caching the composable and reuse it on animation out? Answering your question: since both animations: enter and exit are very subtle, I do not care about video playing or rippleEffect.
m
Yeah, I think that a great feature compose could have is disposable animations. But it looks way more easier to say than to make a stable version 😅