Thiago
03/04/2021, 2:27 PM// Sample 1
.listenParent { progress ->
if (progress < 0.1f) // update opacity state to start opacity animation
else if (progress < 0.25f) // update width state to start width animation
...
}
// Sample 2
@Composable
fun OpacityComposable(parentProgress: Float = 0f, parentTimeMs: Long = 300) {
val target = (parentProgress / 0.1f).coercIn(0f, 1f)
// Ignore the unexpected behavior where the parent restart will first animate opacity to 0f before 1f
val opacity = animateFloatAsState(
targetValue = target,
animationSpec = tween(
durationMillis = parentTimeMs * 0.1f, // Is it the way to keep time sync between them?
easing = LinearOutSlowInEasing // To have an independent curve
)
)
}
Doris Liu
03/04/2021, 8:40 PMTargetBasedAnimation
: https://developer.android.com/jetpack/compose/animation#targetbasedanimation It's the stateless animation that backs up our high level animations. This may take some effort, because... with more power comes more responsibility. 𤣠Alternatively, you could do what you did in sample2, and use the default or a faster spring() to fake the impression of following the progress change. I suspect that should be pretty smooth, though not exactly adhering to the timeline.
⢠If the progress is driven strictly by time. Consider using delay for the animations on the timeline.Doris Liu
03/04/2021, 8:51 PM@Composable
fun <T, V: AnimationVector> childAnimation(
initialValue: T, targetValue: T, typeConverter: TwoWayConverter<T, V>,
progress: Float, parentDuration: Long, startProgress: Float, endProgress:
Float) : T {
val duration = remember(parentDuration, startProgress, endProgress) {
(parentDuration * (endProgress - startProgress)).roundToInt()
}
val delay = remember(parentDuration, startProgress) { (parentDuration * startProgress).roundToInt() }
val animation = remember(initialValue, targetValue, typeConverter, duration, delay) {
TargetBasedAnimation(
initialValue = initialValue,
targetValue = targetValue,
typeConverter = typeConverter,
animationSpec = tween(
durationMillis = duration,
delayMillis = delay,
easing = LinearOutSlowInEasing // To have an independent curve
)
)
}
val playTimeNanos = remember(parentDuration, progress) {
(progress * parentDuration * 1_000_000).toLong()
}
return animation.getValueFromNanos(playTimeNanos)
}
Doris Liu
03/04/2021, 8:52 PMThiago
03/04/2021, 8:58 PMDoris Liu
03/04/2021, 8:59 PM