Ive noticed that `AnimatedContent` skips the trans...
# compose
z
Ive noticed that
AnimatedContent
skips the transition sometimes, despite targetState having changed. Why could that be? Potential bug? Code in 🧡
Copy code
AnimatedContent(
    targetState = size,
    transitionSpec = {
        if (targetState > initialState) {
            SlideEnterVertically
        } else {
            SlideExitVertically
        }
    },
    content = { index ->
        val content = contentMap[index]

        stateHolder.SaveableStateProvider(
            key = index,
            content = content,
        )
    },
)
SlideEnterVertically is
slideInVertically
with
fadeOut
SlideExitVertically is
fadeIn
with
slideOutVertically
Im using this composable to animate changes to a backstack. The animation is smooth and works exactly as expected about 70% of the time, other times it will just snap to the targetState. I can reproduce it by decreasing size twice in a short period of time (<5 ms between). Other than that, it seems pretty random to me.
o
z
Thanks @Oleksandr Balan but I'm not interrupting the animation most of the time when I run into this (only exception is the repro step above) so I don't think it's actually related to that?
Most of the time there's several minuters (or at least seconds) between the animations. I can trigger the bug in your link by pressing back during the animation, but then I still get an animation - it's just different from what I've specified
o
can reproduce it by decreasing size twice in a short period of time (<5 ms between)
Aha, I thought you can only reproduce it when pressing back 🀷 But could be the same cause πŸ€”
z
Most of the time it just happens randomly while using the app. Ill definitely continue keeping an eye on the issue you mentioned as well. Ill prob create an issue for this as well so that they can track it!
d
Could you create a minimal repro project and file a bug? That'd help me repro the issue. πŸ™‚
z
Adding to this, if visibilityThreshold is set to null, animations that happen after the first one seem to be interrupted as per the other mentioned issue. Is this intended? Seems like the animation is then considered running forever if Im not mistaken? 🀯
d
Thanks for the screen recordings. Seems like the first video is the intended behavior? The 2nd video is probably related the existing issue that you already linked regarding interruption. I'm currently looking at that issue btw. Should be fixed soon. What's the 3rd video?
If visibilityThreshold is set to null, we'll just use the default visibility threshold which is 0.01f for each dimension.
Spring animations generally have a long tail in the end getting exponentially closer to the target but not arriving at the target. That's why we needed a visibility threshold so that we know when it's close enough to stop. You could probably try logging
transition.currentState
and
transition.targetState
in AnimatedContent to see how long it took for the enter animations and exit animations to really finish. Each set of content will have their own
Transition
, and they are all child transitions of the AnimatedContent's Transition.
BTW, do you have any preferences for what ideally you'd like to see when enter/exit transitions get interrupted?
z
The animation itself is correct in the first video, yes! It doesnt look very nice with the old content being cut too early though, on a real phone it just feels like the top part of the screen flickers due to the blue disappearing for a moment before the other one slides over it. It would be awesome if the old content stuck around until both enter/exit animations are finished (I know somebody reported an issue for this already though ⭐).
When I log the transition states, I can see that it reaches the targetState slightly later than what I see on screen (as expected). Yet I get the animation interrupted animation when using it; Ill let you decide if thats another bug in and of itself! Also, just to ping back to what this thread was originally about - do you think the animation interrupt "bug" is whats causing the above animation to be skipped at times?
When interrupted: For all the use-cases I have, it would always make sense for the animation to continue towards the new value. Exactly like animateValueAsState does it. The only edge case I can think of is if two screens are added/removed from the backstack simultaneously, in XML (or with activities) they would animate in as separate entities, I think the same thing would be true if interruptions were handled as I described above? Im not entirely sure tbh, and it is an edge-case, currently it just results in no animation at all though so any improvement over that would be lovely!
d
Also, just to ping back to what this thread was originally about - do you think the animation interrupt "bug" is whats causing the above animation to be skipped at times?
Without a repro case, my guess is yes. If you could give me a reproducible skipping. I'd love to investigate. As I'm looking at the animation interruption bug, it seems that when the outgoing content becomes incoming, it records the wrong exit transition when interrupted and tries to reverse that exit transition to become fully visible. For example, instead of trying to reverse a slide out, it would reverse the fade out in your use case. Since the alpha is already at 1f, there's nothing to change, it'll finish the animation immediately. That would be perceived as animation skipping. This issue will be fixed soon, sorry about the wait. πŸ™‚
When interrupted: For all the use-cases I have, it would always make sense for the animation to continue towards the new value. Exactly like animateValueAsState does it.
Curious if you would prefer a sequential change - if transition A->B is interrupted by C, it'd go ahead and finish the A-B section before proceeding to C. Would that be preferable over interrupting B's enter transition and make it exit right away?
z
That makes sense, glad to hear that the fix is coming up! The workaround I mentioned above works surprisingly well for now too πŸ™‚ Any chance that exit/enter content in AnimatedContent will stick around until both animations finish too? Other than these two things, animations in compose have been a bliss to work with and I appreciate all the tweaks that are continiously rolling in. Every other thursday feels like the morning of Christmas eve πŸŽ„ I think Id prefer the sequential approach. It seems like it would hit the sweet spot all of the time for my use-cases at least. The other option would either mean snapping the content of B to its end state and then exiting it, or stopping its slideIn on the spot, only to fade it out? Doesnt seem ideal to me at least πŸ˜…
d
We'll look into having the outgoing content stick around. I initially considered supporting enter/exit to be played sequentially, so that you could do something like
ExitTransition.None after fadeIn() + ...
instead of using
with
. Sequential animations come with its own set of issues around interruptions. So maybe we'll take a different approach to support this request.
I think Id prefer the sequential approach. It seems like it would hit the sweet spot all of the time for my use-cases at least.
I'm starting to think it'd make sense to also have an option to queue up interruptions. Sounds like it'd benefit your use case as well. Thanks for the feedback!
z
I randomly picked up on a pattern in the animation snapping issue earlier today: The animation runs just fine when navigating forwards, size 1->2->3. Navigating backwards from 3->2 is fine, then 2->1 always results in the snapping behavior. If I change my enter/exit transitions to slideInOutVertically, the transition always runs as expected, Im pretty sure that the horizontal versions would do the same, but fade/scale does not regardless of what values I pass in. Hope this can either validate that this is whats getting fixed, or highlight what else needs a patch πŸ˜… Please let me know if a repro would be helpful and Ill try to find some time to do that this week.
d
Im pretty sure that the horizontal versions would do the same, but fade/scale does not regardless of what values I pass in.
That's an interesting observation. The fade/scale indeed have a different impl than shrink/expand/slide. I just checked the implementation nothing really stood out. If you have a repro that'd be the most helpful. If not, you could try out the fix I recently submitted when it's released in a couple of weeks. They may have the same root cause.
Thank you @Zoltan Demant! I will play with it today and see if it's still reproducible after the aforementioned fix. πŸ™‚
z
Hey @Doris Liu! I commented on the issue tracker as well, but thought Id ask you directly if youve had a chance to play around with this yet? blob smile happy I have some versioning issues with the new alpha release of compose, but Im pretty sure my project is bringing in the new release, and the issue is unfortunately still there for me. Id love to know if youre seeing the same thing on your end? And if thats the case, any idea about a solution for it that I could apply until the underlying issue is resolved?
d
Hey Zoltan, thanks for following up. Sorry for the delayed reply. I see the snapping and captured it in the video below. It looks like this is most likely caused by our interruption logic that switches over to spring for interrupted fade. Since the fade has an initial value and a target value that are very close, they finish within 1-2 frames. That's also what I see as I log the alpha. It seems like a different issue to me. Is there a separate bug for this?
z
Hi @Doris Liu! Thank you, you can find the issue here. I do technically use fade for my animation, but only as a means to keep the previous content around (otherwise its removed as soon as the animation starts). Based on my understanding of this, until the issue is resolved Id practically need an (enter) animation that does enough "work" in order for the
slideOutVertically
to be able to finish its work as well? That seems impossible (correct me if Im wrong) considering the spring type deal, but at least good to know if I fully comprehend the issue πŸ˜„
d
I outlined two potential solutions to this issue in the issue tracker. Please take a look and let me know if you have any questions. And yes, you did fully comprehend the issue. πŸ™‚
229 Views