@@ -18,9 +18,11 @@ class ViewPropertySpringAnimator<T : View>(
18
18
}
19
19
20
20
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 > ()
22
24
val isRunning: Boolean
23
- get() = runningAnimations.isNotEmpty()
25
+ get() = animatorMap.values.any { it.isRunning }
24
26
25
27
private var defaultDampingRatio: Float = SpringForce .DAMPING_RATIO_MEDIUM_BOUNCY
26
28
private var defaultStiffness: Float = SpringForce .STIFFNESS_MEDIUM
@@ -40,6 +42,9 @@ class ViewPropertySpringAnimator<T : View>(
40
42
): ViewPropertySpringAnimator <T > =
41
43
animateProperty(DynamicAnimation .X , value, config)
42
44
45
+ /* *
46
+ * Eager evaluate the final value from the current value.
47
+ */
43
48
fun xBy (
44
49
value : Float ,
45
50
config : SpringAnimationConfig .() -> Unit = {}
@@ -52,6 +57,9 @@ class ViewPropertySpringAnimator<T : View>(
52
57
): ViewPropertySpringAnimator <T > =
53
58
animateProperty(DynamicAnimation .Y , value, config)
54
59
60
+ /* *
61
+ * Eager evaluate the final value from the current value.
62
+ */
55
63
fun yBy (
56
64
value : Float ,
57
65
config : SpringAnimationConfig .() -> Unit = {}
@@ -64,6 +72,9 @@ class ViewPropertySpringAnimator<T : View>(
64
72
): ViewPropertySpringAnimator <T > =
65
73
animateProperty(DynamicAnimation .Z , value, config)
66
74
75
+ /* *
76
+ * Eager evaluate the final value from the current value.
77
+ */
67
78
fun zBy (
68
79
value : Float ,
69
80
config : SpringAnimationConfig .() -> Unit = {}
@@ -76,6 +87,9 @@ class ViewPropertySpringAnimator<T : View>(
76
87
): ViewPropertySpringAnimator <T > =
77
88
animateProperty(DynamicAnimation .ROTATION , value, config)
78
89
90
+ /* *
91
+ * Eager evaluate the final value from the current value.
92
+ */
79
93
fun rotationBy (
80
94
value : Float ,
81
95
config : SpringAnimationConfig .() -> Unit = {}
@@ -88,6 +102,9 @@ class ViewPropertySpringAnimator<T : View>(
88
102
): ViewPropertySpringAnimator <T > =
89
103
animateProperty(DynamicAnimation .ROTATION_X , value, config)
90
104
105
+ /* *
106
+ * Eager evaluate the final value from the current value.
107
+ */
91
108
fun rotationXBy (
92
109
value : Float ,
93
110
config : SpringAnimationConfig .() -> Unit = {}
@@ -100,6 +117,9 @@ class ViewPropertySpringAnimator<T : View>(
100
117
): ViewPropertySpringAnimator <T > =
101
118
animateProperty(DynamicAnimation .ROTATION_Y , value, config)
102
119
120
+ /* *
121
+ * Eager evaluate the final value from the current value.
122
+ */
103
123
fun rotationYBy (
104
124
value : Float ,
105
125
config : SpringAnimationConfig .() -> Unit = {}
@@ -112,6 +132,9 @@ class ViewPropertySpringAnimator<T : View>(
112
132
): ViewPropertySpringAnimator <T > =
113
133
animateProperty(DynamicAnimation .TRANSLATION_X , value, config)
114
134
135
+ /* *
136
+ * Eager evaluate the final value from the current value.
137
+ */
115
138
fun translationXBy (
116
139
value : Float ,
117
140
config : SpringAnimationConfig .() -> Unit = {}
@@ -124,6 +147,9 @@ class ViewPropertySpringAnimator<T : View>(
124
147
): ViewPropertySpringAnimator <T > =
125
148
animateProperty(DynamicAnimation .TRANSLATION_Y , value, config)
126
149
150
+ /* *
151
+ * Eager evaluate the final value from the current value.
152
+ */
127
153
fun translationYBy (
128
154
value : Float ,
129
155
config : SpringAnimationConfig .() -> Unit = {}
@@ -136,6 +162,9 @@ class ViewPropertySpringAnimator<T : View>(
136
162
): ViewPropertySpringAnimator <T > =
137
163
animateProperty(DynamicAnimation .TRANSLATION_Z , value, config)
138
164
165
+ /* *
166
+ * Eager evaluate the final value from the current value.
167
+ */
139
168
fun translationZBy (
140
169
value : Float ,
141
170
config : SpringAnimationConfig .() -> Unit = {}
@@ -148,6 +177,9 @@ class ViewPropertySpringAnimator<T : View>(
148
177
): ViewPropertySpringAnimator <T > =
149
178
animateProperty(DynamicAnimation .SCALE_X , value, config)
150
179
180
+ /* *
181
+ * Eager evaluate the final value from the current value.
182
+ */
151
183
fun scaleXBy (
152
184
value : Float ,
153
185
config : SpringAnimationConfig .() -> Unit = {}
@@ -160,6 +192,9 @@ class ViewPropertySpringAnimator<T : View>(
160
192
): ViewPropertySpringAnimator <T > =
161
193
animateProperty(DynamicAnimation .SCALE_Y , value, config)
162
194
195
+ /* *
196
+ * Eager evaluate the final value from the current value.
197
+ */
163
198
fun scaleYBy (
164
199
value : Float ,
165
200
config : SpringAnimationConfig .() -> Unit = {}
@@ -172,12 +207,18 @@ class ViewPropertySpringAnimator<T : View>(
172
207
): ViewPropertySpringAnimator <T > =
173
208
animateProperty(DynamicAnimation .ALPHA , value, config)
174
209
210
+ /* *
211
+ * Eager evaluate the final value from the current value.
212
+ */
175
213
fun alphaBy (
176
214
value : Float ,
177
215
config : SpringAnimationConfig .() -> Unit = {}
178
216
): ViewPropertySpringAnimator <T > =
179
217
animatePropertyBy(DynamicAnimation .ALPHA , value, config)
180
218
219
+ /* *
220
+ * A new [SpringAnimation] will be created every time you call this method.
221
+ */
181
222
fun animateProperty (
182
223
value : Float ,
183
224
setter : T .(Float ) -> Unit ,
@@ -186,6 +227,10 @@ class ViewPropertySpringAnimator<T : View>(
186
227
): ViewPropertySpringAnimator <T > =
187
228
animateProperty(createCustomProperty(setter, getter), value, config)
188
229
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
+ */
189
234
fun animatePropertyBy (
190
235
setter : T .(Float ) -> Unit ,
191
236
getter : T .() -> Float ,
@@ -202,6 +247,9 @@ class ViewPropertySpringAnimator<T : View>(
202
247
animatePropertyInternal(property, value, config)
203
248
}
204
249
250
+ /* *
251
+ * Eager evaluate the final value from the current value.
252
+ */
205
253
fun animatePropertyBy (
206
254
property : FloatPropertyCompat <in T >,
207
255
value : Float ,
@@ -210,46 +258,9 @@ class ViewPropertySpringAnimator<T : View>(
210
258
animatePropertyInternal(property, value + property.getValue(view), config)
211
259
}
212
260
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
-
251
261
@MainThread
252
262
fun start (): ViewPropertySpringAnimator <T > = apply {
263
+ if (pendingAnimations.isEmpty()) return @apply
253
264
val animations = pendingAnimations.toList()
254
265
pendingAnimations.clear()
255
266
animatorListener?.onAnimationStart(this )
@@ -259,16 +270,16 @@ class ViewPropertySpringAnimator<T : View>(
259
270
@MainThread
260
271
fun cancel () {
261
272
pendingAnimations.clear()
262
- val animations = runningAnimations .values.toList()
263
- runningAnimations .clear()
273
+ val animations = animatorMap .values.toList()
274
+ animatorMap .clear()
264
275
animations.forEach { it.cancel() }
265
276
animatorListener?.onAnimationCancel(this )
266
277
}
267
278
268
279
@MainThread
269
280
fun skipToEnd () {
270
281
pendingAnimations.clear()
271
- val animations = runningAnimations .values.toList()
282
+ val animations = animatorMap .values.toList()
272
283
animations.filter { it.canSkipToEnd() }
273
284
.forEach { it.skipToEnd() }
274
285
}
@@ -296,13 +307,13 @@ class ViewPropertySpringAnimator<T : View>(
296
307
}
297
308
298
309
fun removeUpdateListener (listener : DynamicAnimation .OnAnimationUpdateListener ) {
299
- runningAnimations .forEach { (_, animation) ->
310
+ animatorMap .forEach { (_, animation) ->
300
311
animation.removeUpdateListener(listener)
301
312
}
302
313
}
303
314
304
315
fun removeEndListener (listener : DynamicAnimation .OnAnimationEndListener ) {
305
- runningAnimations .forEach { (_, animation) ->
316
+ animatorMap .forEach { (_, animation) ->
306
317
animation.removeEndListener(listener)
307
318
}
308
319
}
@@ -319,4 +330,42 @@ class ViewPropertySpringAnimator<T : View>(
319
330
setter.invoke(view, value)
320
331
}
321
332
}
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
+ }
322
371
}
0 commit comments