Skip to content

Commit 4f43f78

Browse files
authored
Merge pull request #8 from lcdsmao/refactor-viewpropertyspringanimator
Refactor
2 parents 0d8ebb4 + 003e04a commit 4f43f78

File tree

1 file changed

+94
-45
lines changed

1 file changed

+94
-45
lines changed

library/src/main/java/com/github/lcdsmao/springx/ViewPropertySpringAnimator.kt

+94-45
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)