diff options
4 files changed, 123 insertions, 31 deletions
diff --git a/core-ui/src/main/res-public/values/public.xml b/core-ui/src/main/res-public/values/public.xml index 193e088..f46b3eb 100644 --- a/core-ui/src/main/res-public/values/public.xml +++ b/core-ui/src/main/res-public/values/public.xml @@ -1,7 +1,7 @@ <resources xmlns:tools='http://schemas.android.com/tools' tools:ignore='ResourceName'> <!-- AUTO-GENERATED FILE. DO NOT MODIFY. public.xml is generated by the generatepublicxml gradle task --> - <public name='kau_elastic_recycler_activity' type='layout' /> <public name='kau_recycler_detached_background' type='layout' /> + <public name='kau_elastic_recycler_activity' type='layout' /> <public name='kau_recycler_textslider' type='layout' /> <public name='Kau.Translucent' type='style' /> <public name='Kau.Translucent.NoAnimation' type='style' /> diff --git a/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt b/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt index 39e8657..b98a47e 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt @@ -3,6 +3,7 @@ package ca.allanwang.kau.ui import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator +import android.support.annotation.VisibleForTesting import ca.allanwang.kau.kotlin.kauRemoveIf /** @@ -57,12 +58,17 @@ class ProgressAnimator private constructor() : ValueAnimator() { } private val animators: MutableList<ProgressDisposableAction> = mutableListOf() - private val startActions: MutableList<ProgressDisposableRunnable> = mutableListOf() - private val cancelActions: MutableList<ProgressDisposableRunnable> = mutableListOf() - private val endActions: MutableList<ProgressDisposableRunnable> = mutableListOf() + @VisibleForTesting + internal val startActions: MutableList<ProgressDisposableRunnable> = mutableListOf() + @VisibleForTesting + internal val cancelActions: MutableList<ProgressDisposableRunnable> = mutableListOf() + @VisibleForTesting + internal val endActions: MutableList<ProgressDisposableRunnable> = mutableListOf() var isCancelled: Boolean = false private set + val animatorCount get() = animators.size + /** * Converts an action to a disposable action @@ -80,8 +86,10 @@ class ProgressAnimator private constructor() : ValueAnimator() { return condition } - private fun MutableList<ProgressDisposableRunnable>.runAll() = kauRemoveIf { it() } + @VisibleForTesting + internal fun MutableList<ProgressDisposableRunnable>.runAll() = kauRemoveIf { it() } + @VisibleForTesting internal fun apply(progress: Float) { animators.kauRemoveIf { it(progress) } } @@ -109,16 +117,16 @@ class ProgressAnimator private constructor() : ValueAnimator() { if (min >= max) { throw IllegalArgumentException("Range animator must have min < max; currently min=$min, max=$max") } - withDisposableAnimator { - when { - it > max -> true - it < min -> false - else -> { - action(progress(start, end, progress, min, max)) - false - } + withDisposableAnimator { + when { + it > max -> true + it < min -> false + else -> { + action(progress(start, end, progress, min, max)) + false } } + } } fun withPointAnimator(point: Float, action: ProgressAction) { @@ -141,13 +149,22 @@ class ProgressAnimator private constructor() : ValueAnimator() { fun withDisposableStartAction(action: ProgressDisposableRunnable) = startActions.add(action) - fun withCancelAction(action:ProgressRunnable) = withDisposableCancelAction(action.asDisposable()) + fun withCancelAction(action: ProgressRunnable) = withDisposableCancelAction(action.asDisposable()) fun withDisposableCancelAction(action: ProgressDisposableRunnable) = cancelActions.add(action) fun withEndAction(action: ProgressRunnable) = withDisposableEndAction(action.asDisposable()) fun withDisposableEndAction(action: ProgressDisposableRunnable) = endActions.add(action) + + fun reset() { + if (isRunning) cancel() + animators.clear() + startActions.clear() + cancelActions.clear() + endActions.clear() + isCancelled = false + } } private typealias ProgressAction = (Float) -> Unit diff --git a/core/src/main/res-public/values/public.xml b/core/src/main/res-public/values/public.xml index 2163b10..ea8ed73 100644 --- a/core/src/main/res-public/values/public.xml +++ b/core/src/main/res-public/values/public.xml @@ -1,27 +1,19 @@ <resources xmlns:tools='http://schemas.android.com/tools' tools:ignore='ResourceName'> <!-- AUTO-GENERATED FILE. DO NOT MODIFY. public.xml is generated by the generatepublicxml gradle task --> - <public name='kau_fade_in' type='anim' /> - <public name='kau_fade_out' type='anim' /> - <public name='kau_slide_in_bottom' type='anim' /> - <public name='kau_slide_in_left' type='anim' /> - <public name='kau_slide_in_right' type='anim' /> <public name='kau_slide_in_top' type='anim' /> - <public name='kau_slide_out_bottom' type='anim' /> - <public name='kau_slide_out_left' type='anim' /> - <public name='kau_slide_out_left_top' type='anim' /> + <public name='kau_slide_in_left' type='anim' /> <public name='kau_slide_out_right' type='anim' /> <public name='kau_slide_out_right_top' type='anim' /> + <public name='kau_fade_in' type='anim' /> <public name='kau_slide_out_top' type='anim' /> - <public name='kau_selectable_white' type='drawable' /> + <public name='kau_slide_out_bottom' type='anim' /> + <public name='kau_fade_out' type='anim' /> + <public name='kau_slide_out_left' type='anim' /> + <public name='kau_slide_out_left_top' type='anim' /> + <public name='kau_slide_in_bottom' type='anim' /> + <public name='kau_slide_in_right' type='anim' /> <public name='kau_transparent' type='drawable' /> - <public name='kau_enter_slide_bottom' type='transition' /> - <public name='kau_enter_slide_left' type='transition' /> - <public name='kau_enter_slide_right' type='transition' /> - <public name='kau_enter_slide_top' type='transition' /> - <public name='kau_exit_slide_bottom' type='transition' /> - <public name='kau_exit_slide_left' type='transition' /> - <public name='kau_exit_slide_right' type='transition' /> - <public name='kau_exit_slide_top' type='transition' /> + <public name='kau_selectable_white' type='drawable' /> <public name='kau_shadow_overlay' type='color' /> <public name='kau_activity_horizontal_margin' type='dimen' /> <public name='kau_activity_vertical_margin' type='dimen' /> @@ -115,4 +107,12 @@ <public name='KauSlideInFadeOut' type='style' /> <public name='KauSlideInSlideOutRight' type='style' /> <public name='KauSlideInSlideOutBottom' type='style' /> + <public name='kau_enter_slide_bottom' type='transition' /> + <public name='kau_enter_slide_top' type='transition' /> + <public name='kau_exit_slide_bottom' type='transition' /> + <public name='kau_exit_slide_top' type='transition' /> + <public name='kau_enter_slide_right' type='transition' /> + <public name='kau_exit_slide_right' type='transition' /> + <public name='kau_exit_slide_left' type='transition' /> + <public name='kau_enter_slide_left' type='transition' /> </resources>
\ No newline at end of file diff --git a/core/src/test/kotlin/ca/allanwang/kau/ui/ProgressAnimatorTest.kt b/core/src/test/kotlin/ca/allanwang/kau/ui/ProgressAnimatorTest.kt new file mode 100644 index 0000000..60f8680 --- /dev/null +++ b/core/src/test/kotlin/ca/allanwang/kau/ui/ProgressAnimatorTest.kt @@ -0,0 +1,75 @@ +package ca.allanwang.kau.ui + +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class ProgressAnimatorTest { + + private fun ProgressAnimator.test() { + startActions.runAll() + var value = 0f + while (value < 1f) { + apply(value) + value += 0.05f + } + apply(1f) + endActions.runAll() + } + + @Test + fun `basic run`() { + var i = 0f + ProgressAnimator.ofFloat { + withAnimator { + i = it + } + }.test() + assertEquals(1f, i) + } + + @Test + fun `start end hooks`() { + var i = 0 + ProgressAnimator.ofFloat { + withStartAction { i = 1 } + withDisposableAnimator { assertEquals(1, i); true } + withEndAction { + assertEquals(0, animatorCount, "Disposable animator not removed") + i = 2 + } + }.test() + assertEquals(2, i) + } + + @Test + fun `disposable actions`() { + var i = 0f + ProgressAnimator.ofFloat { + withDisposableAnimator { + i = if (it < 0.5f) it else 0.5f + i > 0.5f + } + withAnimator { + assertEquals(Math.min(it, 0.5f), i) + } + }.test() + } + + @Test + fun `point action`() { + var called = false + var i = 0f + ProgressAnimator.ofFloat { + withPointAnimator(0.5f) { + assertFalse(called) + i = it + called = true + } + }.test() + assertTrue(called) + assertTrue(i > 0.5f) + } + +}
\ No newline at end of file |