Zsolt
11/09/2021, 10:50 PMupdateTransition
, any updates to the targetState
seem to not respect the passed transitionSpec
but to create a new one with default values.
E.g.:
1. Have an updateTransition.animateFloat
with transitionSpec = { tween(4000, 0, LinearEasing) }
2. Start a transition between states A → B
3. While the transition is running, set a new targetState
for the transition: C
ER: The transition towards the new state finishes in 4000ms
with LinearEasing
AR: The transition towards the new state finishes in 300ms
with FastOutSlowIn
easing (default values of TweenSpec
)Zsolt
11/09/2021, 10:58 PMprivate enum class SomeState {
State1,
State2,
State3,
}
@Composable
private fun SpecTest() {
val currentState = remember { MutableTransitionState(SomeState.State1) }
val animatedValue = DoStuff(currentState)
Log.d("Spec test", animatedValue.value.toString())
LaunchedEffect(Unit) {
delay(50)
Log.d("Spec test", "New target: State 2")
currentState.targetState = SomeState.State2
}
LaunchedEffect(Unit) {
delay(1250)
Log.d("Spec test", "New target: State 3")
currentState.targetState = SomeState.State3
}
}
@Composable
private fun DoStuff(currentState: MutableTransitionState<SomeState>): State<Float> {
val transition = updateTransition(currentState)
val animatedValue = transition.animateFloat(
transitionSpec = { tween(4000, 0, LinearEasing) },
targetValueByState = {
when (it) {
SomeState.State1 -> 0f
SomeState.State2 -> -10f
SomeState.State3 -> 10f
}
}
)
return animatedValue
}
Zsolt
11/09/2021, 10:58 PM22:55:33.183 D/Spec test: New target: State 2
22:55:33.197 D/Spec test: 0.0
22:55:33.213 D/Spec test: 0.0
22:55:33.228 D/Spec test: -0.040000003
22:55:33.245 D/Spec test: -0.080000006
22:55:33.261 D/Spec test: -0.122499995
22:55:33.277 D/Spec test: -0.1625
22:55:33.294 D/Spec test: -0.2025
22:55:33.311 D/Spec test: -0.24499999
22:55:33.326 D/Spec test: -0.285
22:55:33.343 D/Spec test: -0.325
22:55:33.359 D/Spec test: -0.3675
22:55:33.375 D/Spec test: -0.4075
22:55:33.392 D/Spec test: -0.45000002
22:55:33.408 D/Spec test: -0.48999998
22:55:33.425 D/Spec test: -0.53
22:55:33.441 D/Spec test: -0.5725
22:55:33.457 D/Spec test: -0.6125
22:55:33.473 D/Spec test: -0.65250003
22:55:33.489 D/Spec test: -0.695
22:55:33.506 D/Spec test: -0.735
22:55:33.523 D/Spec test: -0.775
22:55:33.539 D/Spec test: -0.8175
22:55:33.555 D/Spec test: -0.85749996
22:55:33.571 D/Spec test: -0.90000004
22:55:33.587 D/Spec test: -0.93999994
22:55:33.604 D/Spec test: -0.97999996
22:55:33.620 D/Spec test: -1.0225
22:55:33.637 D/Spec test: -1.0625
22:55:33.653 D/Spec test: -1.1025001
22:55:33.669 D/Spec test: -1.145
22:55:33.686 D/Spec test: -1.1850001
22:55:33.702 D/Spec test: -1.2275
22:55:33.719 D/Spec test: -1.2675
22:55:33.735 D/Spec test: -1.3075
22:55:33.751 D/Spec test: -1.35
22:55:33.768 D/Spec test: -1.39
22:55:33.784 D/Spec test: -1.4300001
22:55:33.800 D/Spec test: -1.4725
22:55:33.817 D/Spec test: -1.5125
22:55:33.833 D/Spec test: -1.5525
22:55:33.849 D/Spec test: -1.595
22:55:33.866 D/Spec test: -1.635
22:55:33.882 D/Spec test: -1.6775
22:55:33.898 D/Spec test: -1.7175
22:55:33.915 D/Spec test: -1.7575
22:55:33.931 D/Spec test: -1.8000001
22:55:33.947 D/Spec test: -1.84
22:55:33.964 D/Spec test: -1.8799999
22:55:33.980 D/Spec test: -1.9225
22:55:33.996 D/Spec test: -1.9625001
22:55:34.013 D/Spec test: -2.0025
22:55:34.029 D/Spec test: -2.045
22:55:34.045 D/Spec test: -2.085
22:55:34.062 D/Spec test: -2.1275
22:55:34.078 D/Spec test: -2.1675
22:55:34.095 D/Spec test: -2.2075
22:55:34.111 D/Spec test: -2.25
22:55:34.127 D/Spec test: -2.29
22:55:34.144 D/Spec test: -2.33
22:55:34.173 D/Spec test: -2.3725
22:55:34.176 D/Spec test: -2.4125
22:55:34.193 D/Spec test: -2.4525
22:55:34.209 D/Spec test: -2.4950001
22:55:34.226 D/Spec test: -2.535
22:55:34.242 D/Spec test: -2.5775
22:55:34.258 D/Spec test: -2.6175
22:55:34.275 D/Spec test: -2.6574998
22:55:34.291 D/Spec test: -2.7
22:55:34.307 D/Spec test: -2.7399998
22:55:34.323 D/Spec test: -2.78
22:55:34.339 D/Spec test: -2.8224998
22:55:34.356 D/Spec test: -2.8625
22:55:34.372 D/Spec test: -2.9025002
22:55:34.385 D/Spec test: New target: State 3
22:55:34.391 D/Spec test: -2.945
22:55:34.406 D/Spec test: -1.3040949
22:55:34.422 D/Spec test: 1.582622
22:55:34.440 D/Spec test: 4.3585196
22:55:34.457 D/Spec test: 6.3139114
22:55:34.473 D/Spec test: 7.6665077
22:55:34.489 D/Spec test: 8.59953
22:55:34.505 D/Spec test: 9.148899
22:55:34.521 D/Spec test: 9.48955
22:55:34.538 D/Spec test: 9.7069
22:55:34.554 D/Spec test: 9.827664
22:55:34.571 D/Spec test: 9.902748
22:55:34.587 D/Spec test: 9.943596
22:55:34.604 D/Spec test: 9.967458
22:55:34.621 D/Spec test: 9.981949
22:55:34.638 D/Spec test: 10.0
Doris Liu
11/10/2021, 5:21 AMDoris Liu
11/10/2021, 5:23 AMZsolt
11/10/2021, 9:54 AMTween works somewhat well, but can significantly increase/shorten the overall duration. E.g. Interrupted when nearly finished, and therefore start another 500ms long tween.Actually both these use-cases can make sense to client code in different situations: 1. reusing the remaining amount of time to finish animating towards a new target – adds predictability to carry out an operation on the UI in a given time 2. restarting the timer on every interruption – adds a fluid UX for interacting with the UI when end time is not important It would be great to have this as a configuration parameter. And then I assume the base scenario could work as well?
Doris Liu
11/10/2021, 10:42 PMreusing the remaining amount of time to finish animating towards a new target – adds predictability to carry out an operation on the UI in a given timeThis has the potential to look very strange - you could be interrupted when there's 30ms remaining from the interrupted animation, and quickly arriving at the new target within 30 ms could look like a jump cut.
restarting the timer on every interruption – adds a fluid UX for interacting with the UI when end time is not importantThis is what we ended up doing using springs - the timer is restarted and the value & velocity at the point of interruption is accounted for in the spring animation.
It would be great to have this as a configuration parameter. And then I assume the base scenario could work as well?We'll look into making this configurable. In the meantime, I'd suggest trying out the idea of reusing the remaining time in a prototype (maybe using Animatable) to see whether that's desirable for your use case. 🙂 Thanks for filing the feature request