aboutsummaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/kotlin/ca/allanwang/kau/ui/ProgressAnimator.kt43
-rw-r--r--core/src/main/res-public/values/public.xml34
-rw-r--r--core/src/test/kotlin/ca/allanwang/kau/ui/ProgressAnimatorTest.kt75
3 files changed, 122 insertions, 30 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
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