diff options
Diffstat (limited to 'core/src/main/kotlin')
-rw-r--r-- | core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt b/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt new file mode 100644 index 0000000..dc10e71 --- /dev/null +++ b/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt @@ -0,0 +1,85 @@ +package ca.allanwang.kau.ui + +import android.animation.Animator +import android.animation.AnimatorListenerAdapter +import android.animation.ValueAnimator +import android.view.animation.Interpolator + +/** + * Created by Allan Wang on 2017-11-10. + * + * Wrapper for value animator specifically dealing with progress values + * This is typically a float range of 0 to 1, but can be customized + * This differs in that everything can be done with simple listeners, which will be bundled + * and added to the backing [ValueAnimator] + */ +class ProgressAnimator private constructor(private vararg val values: Float) { + + companion object { + inline fun ofFloat(crossinline builder: ProgressAnimator.() -> Unit) = ofFloat(0f, 1f) { builder() } + + fun ofFloat(vararg values: Float, builder: ProgressAnimator.() -> Unit) = ProgressAnimator(*values).apply { + builder() + build() + } + } + + private val animators: MutableList<(Float) -> Unit> = mutableListOf() + private val startActions: MutableList<() -> Unit> = mutableListOf() + private val endActions: MutableList<() -> Unit> = mutableListOf() + + var duration: Long = -1L + var interpolator: Interpolator? = null + + /** + * Add more changes to the [ValueAnimator] before running + */ + var extraConfigs: ValueAnimator.() -> Unit = {} + + /** + * Range animator. Multiples the range by the current float progress before emission + */ + fun withAnimator(from: Float, to: Float, animator: (Float) -> Unit) = animators.add { + val range = to - from + animator(range * it + from) + } + + /** + * Standard animator. Emits progress value as is + */ + fun withAnimator(animator: (Float) -> Unit) = animators.add(animator) + + /** + * Start action to be called once when the animator first begins + */ + fun withStartAction(action: () -> Unit) = startActions.add(action) + + /** + * End action to be called once when the animator ends + */ + fun withEndAction(action: () -> Unit) = endActions.add(action) + + fun build() { + ValueAnimator.ofFloat(*values).apply { + if (this@ProgressAnimator.duration > 0L) + duration = this@ProgressAnimator.duration + if (this@ProgressAnimator.interpolator != null) + interpolator = this@ProgressAnimator.interpolator + addUpdateListener { + val progress = it.animatedValue as Float + animators.forEach { it(progress) } + } + addListener(object : AnimatorListenerAdapter() { + override fun onAnimationStart(animation: Animator?) { + startActions.forEach { it() } + } + + override fun onAnimationEnd(animation: Animator?) { + endActions.forEach { it() } + } + }) + extraConfigs() + start() + } + } +}
\ No newline at end of file |