@@ -18,9 +18,11 @@ class ViewPropertySpringAnimator<T : View>(
1818 }
1919
2020 private val pendingAnimations = mutableListOf<SpringAnimationHolder >()
21- private val runningAnimations = mutableMapOf<FloatPropertyCompat <in T >, SpringAnimation > ()
21+
22+ // Contains pending animations and running animations
23+ private val animatorMap = mutableMapOf<FloatPropertyCompat <in T >, SpringAnimation > ()
2224 val isRunning: Boolean
23- get() = runningAnimations.isNotEmpty()
25+ get() = animatorMap.values.any { it.isRunning }
2426
2527 private var defaultDampingRatio: Float = SpringForce .DAMPING_RATIO_MEDIUM_BOUNCY
2628 private var defaultStiffness: Float = SpringForce .STIFFNESS_MEDIUM
@@ -40,6 +42,9 @@ class ViewPropertySpringAnimator<T : View>(
4042 ): ViewPropertySpringAnimator <T > =
4143 animateProperty(DynamicAnimation .X , value, config)
4244
45+ /* *
46+ * Eager evaluate the final value from the current value.
47+ */
4348 fun xBy (
4449 value : Float ,
4550 config : SpringAnimationConfig .() -> Unit = {}
@@ -52,6 +57,9 @@ class ViewPropertySpringAnimator<T : View>(
5257 ): ViewPropertySpringAnimator <T > =
5358 animateProperty(DynamicAnimation .Y , value, config)
5459
60+ /* *
61+ * Eager evaluate the final value from the current value.
62+ */
5563 fun yBy (
5664 value : Float ,
5765 config : SpringAnimationConfig .() -> Unit = {}
@@ -64,6 +72,9 @@ class ViewPropertySpringAnimator<T : View>(
6472 ): ViewPropertySpringAnimator <T > =
6573 animateProperty(DynamicAnimation .Z , value, config)
6674
75+ /* *
76+ * Eager evaluate the final value from the current value.
77+ */
6778 fun zBy (
6879 value : Float ,
6980 config : SpringAnimationConfig .() -> Unit = {}
@@ -76,6 +87,9 @@ class ViewPropertySpringAnimator<T : View>(
7687 ): ViewPropertySpringAnimator <T > =
7788 animateProperty(DynamicAnimation .ROTATION , value, config)
7889
90+ /* *
91+ * Eager evaluate the final value from the current value.
92+ */
7993 fun rotationBy (
8094 value : Float ,
8195 config : SpringAnimationConfig .() -> Unit = {}
@@ -88,6 +102,9 @@ class ViewPropertySpringAnimator<T : View>(
88102 ): ViewPropertySpringAnimator <T > =
89103 animateProperty(DynamicAnimation .ROTATION_X , value, config)
90104
105+ /* *
106+ * Eager evaluate the final value from the current value.
107+ */
91108 fun rotationXBy (
92109 value : Float ,
93110 config : SpringAnimationConfig .() -> Unit = {}
@@ -100,6 +117,9 @@ class ViewPropertySpringAnimator<T : View>(
100117 ): ViewPropertySpringAnimator <T > =
101118 animateProperty(DynamicAnimation .ROTATION_Y , value, config)
102119
120+ /* *
121+ * Eager evaluate the final value from the current value.
122+ */
103123 fun rotationYBy (
104124 value : Float ,
105125 config : SpringAnimationConfig .() -> Unit = {}
@@ -112,6 +132,9 @@ class ViewPropertySpringAnimator<T : View>(
112132 ): ViewPropertySpringAnimator <T > =
113133 animateProperty(DynamicAnimation .TRANSLATION_X , value, config)
114134
135+ /* *
136+ * Eager evaluate the final value from the current value.
137+ */
115138 fun translationXBy (
116139 value : Float ,
117140 config : SpringAnimationConfig .() -> Unit = {}
@@ -124,6 +147,9 @@ class ViewPropertySpringAnimator<T : View>(
124147 ): ViewPropertySpringAnimator <T > =
125148 animateProperty(DynamicAnimation .TRANSLATION_Y , value, config)
126149
150+ /* *
151+ * Eager evaluate the final value from the current value.
152+ */
127153 fun translationYBy (
128154 value : Float ,
129155 config : SpringAnimationConfig .() -> Unit = {}
@@ -136,6 +162,9 @@ class ViewPropertySpringAnimator<T : View>(
136162 ): ViewPropertySpringAnimator <T > =
137163 animateProperty(DynamicAnimation .TRANSLATION_Z , value, config)
138164
165+ /* *
166+ * Eager evaluate the final value from the current value.
167+ */
139168 fun translationZBy (
140169 value : Float ,
141170 config : SpringAnimationConfig .() -> Unit = {}
@@ -148,6 +177,9 @@ class ViewPropertySpringAnimator<T : View>(
148177 ): ViewPropertySpringAnimator <T > =
149178 animateProperty(DynamicAnimation .SCALE_X , value, config)
150179
180+ /* *
181+ * Eager evaluate the final value from the current value.
182+ */
151183 fun scaleXBy (
152184 value : Float ,
153185 config : SpringAnimationConfig .() -> Unit = {}
@@ -160,6 +192,9 @@ class ViewPropertySpringAnimator<T : View>(
160192 ): ViewPropertySpringAnimator <T > =
161193 animateProperty(DynamicAnimation .SCALE_Y , value, config)
162194
195+ /* *
196+ * Eager evaluate the final value from the current value.
197+ */
163198 fun scaleYBy (
164199 value : Float ,
165200 config : SpringAnimationConfig .() -> Unit = {}
@@ -172,12 +207,18 @@ class ViewPropertySpringAnimator<T : View>(
172207 ): ViewPropertySpringAnimator <T > =
173208 animateProperty(DynamicAnimation .ALPHA , value, config)
174209
210+ /* *
211+ * Eager evaluate the final value from the current value.
212+ */
175213 fun alphaBy (
176214 value : Float ,
177215 config : SpringAnimationConfig .() -> Unit = {}
178216 ): ViewPropertySpringAnimator <T > =
179217 animatePropertyBy(DynamicAnimation .ALPHA , value, config)
180218
219+ /* *
220+ * A new [SpringAnimation] will be created every time you call this method.
221+ */
181222 fun animateProperty (
182223 value : Float ,
183224 setter : T .(Float ) -> Unit ,
@@ -186,6 +227,10 @@ class ViewPropertySpringAnimator<T : View>(
186227 ): ViewPropertySpringAnimator <T > =
187228 animateProperty(createCustomProperty(setter, getter), value, config)
188229
230+ /* *
231+ * Eager evaluate the final value from the current value.
232+ * A new [SpringAnimation] will be created every time you call this method.
233+ */
189234 fun animatePropertyBy (
190235 setter : T .(Float ) -> Unit ,
191236 getter : T .() -> Float ,
@@ -202,6 +247,9 @@ class ViewPropertySpringAnimator<T : View>(
202247 animatePropertyInternal(property, value, config)
203248 }
204249
250+ /* *
251+ * Eager evaluate the final value from the current value.
252+ */
205253 fun animatePropertyBy (
206254 property : FloatPropertyCompat <in T >,
207255 value : Float ,
@@ -210,46 +258,9 @@ class ViewPropertySpringAnimator<T : View>(
210258 animatePropertyInternal(property, value + property.getValue(view), config)
211259 }
212260
213- private fun animatePropertyInternal (
214- property : FloatPropertyCompat <in T >,
215- finalValue : Float ,
216- configBuilder : SpringAnimationConfig .() -> Unit = {}
217- ) {
218- var anim = runningAnimations[property]
219- if (anim == null ) {
220- anim = SpringAnimation (view, property)
221- anim.createEndListener(property)
222- runningAnimations[property] = anim
223- }
224- val config = SpringAnimationConfig (finalValue).apply (configBuilder)
225- config.defaultDampingRatio = defaultDampingRatio
226- config.defaultStiffness = defaultStiffness
227- pendingAnimations + = SpringAnimationHolder (anim, config)
228- }
229-
230- private fun SpringAnimation.createEndListener (
231- property : FloatPropertyCompat <in T >
232- ) {
233- val listener = object : DynamicAnimation .OnAnimationEndListener {
234- override fun onAnimationEnd (
235- animation : DynamicAnimation <out DynamicAnimation <* >>? ,
236- canceled : Boolean ,
237- value : Float ,
238- velocity : Float
239- ) {
240- runningAnimations.remove(property)
241- animation?.removeEndListener(this )
242-
243- if (runningAnimations.isEmpty() && ! canceled) {
244- animatorListener?.onAnimationEnd(this @ViewPropertySpringAnimator)
245- }
246- }
247- }
248- addEndListener(listener)
249- }
250-
251261 @MainThread
252262 fun start (): ViewPropertySpringAnimator <T > = apply {
263+ if (pendingAnimations.isEmpty()) return @apply
253264 val animations = pendingAnimations.toList()
254265 pendingAnimations.clear()
255266 animatorListener?.onAnimationStart(this )
@@ -259,16 +270,16 @@ class ViewPropertySpringAnimator<T : View>(
259270 @MainThread
260271 fun cancel () {
261272 pendingAnimations.clear()
262- val animations = runningAnimations .values.toList()
263- runningAnimations .clear()
273+ val animations = animatorMap .values.toList()
274+ animatorMap .clear()
264275 animations.forEach { it.cancel() }
265276 animatorListener?.onAnimationCancel(this )
266277 }
267278
268279 @MainThread
269280 fun skipToEnd () {
270281 pendingAnimations.clear()
271- val animations = runningAnimations .values.toList()
282+ val animations = animatorMap .values.toList()
272283 animations.filter { it.canSkipToEnd() }
273284 .forEach { it.skipToEnd() }
274285 }
@@ -296,13 +307,13 @@ class ViewPropertySpringAnimator<T : View>(
296307 }
297308
298309 fun removeUpdateListener (listener : DynamicAnimation .OnAnimationUpdateListener ) {
299- runningAnimations .forEach { (_, animation) ->
310+ animatorMap .forEach { (_, animation) ->
300311 animation.removeUpdateListener(listener)
301312 }
302313 }
303314
304315 fun removeEndListener (listener : DynamicAnimation .OnAnimationEndListener ) {
305- runningAnimations .forEach { (_, animation) ->
316+ animatorMap .forEach { (_, animation) ->
306317 animation.removeEndListener(listener)
307318 }
308319 }
@@ -319,4 +330,42 @@ class ViewPropertySpringAnimator<T : View>(
319330 setter.invoke(view, value)
320331 }
321332 }
333+
334+ private fun animatePropertyInternal (
335+ property : FloatPropertyCompat <in T >,
336+ finalValue : Float ,
337+ configBuilder : SpringAnimationConfig .() -> Unit = {}
338+ ) {
339+ var anim = animatorMap[property]
340+ if (anim == null ) {
341+ anim = SpringAnimation (view, property)
342+ anim.cleanSelfOnEnd(property)
343+ animatorMap[property] = anim
344+ }
345+ val config = SpringAnimationConfig (finalValue).apply (configBuilder)
346+ config.defaultDampingRatio = defaultDampingRatio
347+ config.defaultStiffness = defaultStiffness
348+ pendingAnimations + = SpringAnimationHolder (anim, config)
349+ }
350+
351+ private fun SpringAnimation.cleanSelfOnEnd (
352+ property : FloatPropertyCompat <in T >
353+ ) {
354+ val listener = object : DynamicAnimation .OnAnimationEndListener {
355+ override fun onAnimationEnd (
356+ animation : DynamicAnimation <out DynamicAnimation <* >>? ,
357+ canceled : Boolean ,
358+ value : Float ,
359+ velocity : Float
360+ ) {
361+ animatorMap.remove(property)
362+ animation?.removeEndListener(this )
363+
364+ if (animatorMap.isEmpty() && ! canceled) {
365+ animatorListener?.onAnimationEnd(this @ViewPropertySpringAnimator)
366+ }
367+ }
368+ }
369+ addEndListener(listener)
370+ }
322371}
0 commit comments