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.@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)
}
Thiago
03/04/2021, 8:58 PMDoris Liu
03/04/2021, 8:59 PM