Status Update
Comments
di...@gmail.com <di...@gmail.com> #2
Can you try with the latest snapshot? Not reproducible for me on androidx-main.
ti...@google.com <ti...@google.com> #3
Ok, after trying a couple more versions, realized this is a duplicate of
From the release notes:
AndroidView's update callback's first invocation will now be defered until the view is attached, instead of running when the composition that introduces the AndroidView is applied. This fixes a bug where the update callback wouldn't be invalidated if a state it read was changed immediately by an effect. (Ie9438,
) b/291094055
Sorry for the confusion!
ti...@google.com <ti...@google.com> #4
After some investigation, there's indeed some wait in SeekableTransition
that produces different timing for the animateTo
invoked with vs. without withFrameNanos
More specifically, when animateTo
is invoked, seekable transition gets its start time by waiting for a frame:
This means, withFrameNanos { launch(Dispatchers.Main.immediate) { seekableTransitionState.animateTo(value) } }
invokes animateTo
in the frame callback, it would then wait for a whole frame to acquire the start time, because it has missed the beginning of current round of frame dispatch. The start time will therefore be acquired after the jank that happened later in the current frame.
In contrast, with scope.launch { seekableTransitionState.animateTo(value) }
, by the time animateTo
is invoked, the current frame's frame dispatch hasn't happened yet. (see:
The visual difference is the result of different start time for the animation, one starts before the jank, the other starts after the jank.
ti...@google.com <ti...@google.com> #5
The repro in
It is worth provide a way to de-couple composing content from starting the animation. One potential viable solution to experiement with: Leverage PreEnter
state for AnimatedVisibility, and create an API to first finish composing the content without drawing in the PreEnter
state, then allow devs to trigger when to animate to Visible
state.
Description
Jetpack Compose version: 1.7.5 Jetpack Compose component used: Animation
I'm using AnimatedVisibility as a core navigation component, and as such, some of the content lambdas it receives have expensive first compositions. In Enter transitions, I noticed different frame timing characteristics when a SeekableTransitionState vs MutableTransitionState drives the AnimatedVisibility of slow content.
With MutableTransitionState, the content is composed, and the animation starts after the content is composed. This is desirable, as even though my content drops frames, the animation is smooth.
But with SeekableTransitionState, the animation seems to start in the same frame my content is composed, and so every dropped frame is dropped from the animation as well. This results in much more perceptible jank, as even though the same amount of frames are dropped as in the other case, the animation itself doesn't get to play all of its frames.
Weirdly, if I trigger the
SeekableTransitionState::animateTo
inside awithFrameNanos { }
, I get the desired timing again. That's a workaround I'm using for now, but I have no idea why it works.Here's a sample demonstrating the frame timing behaviors: