Add Animation Clock support to AnimatedValue
This CL updates AnimatedValue to use an AnimationClockObservable for
ticking, and thus removing the dependency on Choreographer.
Test: Unit tests added in commit
Bug: 144878730
Change-Id: I2cd43380a1c69ee49ace6fd6eaf1c8ab44ef94d0
diff --git a/ui/ui-animation-core/api/0.1.0-dev04.txt b/ui/ui-animation-core/api/0.1.0-dev04.txt
index e1b1920..61912a7 100644
--- a/ui/ui-animation-core/api/0.1.0-dev04.txt
+++ b/ui/ui-animation-core/api/0.1.0-dev04.txt
@@ -2,9 +2,10 @@
package androidx.animation {
public final class AnimatedFloat extends androidx.animation.BaseAnimatedValue<java.lang.Float,androidx.animation.AnimationVector1D> {
- ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
- ctor public AnimatedFloat(float initVal);
- method public void doAnimationFrame$lintWithKotlin(long time);
+ ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedFloat(float initVal, androidx.animation.AnimationClockObservable clock);
+ ctor @Deprecated public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
+ method public void doAnimationFrame$lintWithKotlin(long timeMillis);
method public float getVelocity();
method public void setBounds(float min = Float.NEGATIVE_INFINITY, float max = Float.POSITIVE_INFINITY);
method public void snapTo(float targetValue);
@@ -12,7 +13,7 @@
}
public final class AnimatedValue<T, V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<T,V> {
- ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter);
+ ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter, androidx.animation.AnimationClockObservable clock);
method public V getVelocity();
property public final V velocity;
}
@@ -23,8 +24,8 @@
}
public final class AnimatedVectorValue<V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<V,V> {
- ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder);
- ctor public AnimatedVectorValue(V initVal);
+ ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedVectorValue(V initVal, androidx.animation.AnimationClockObservable clock);
}
public abstract class AnimationBuilder<T> {
diff --git a/ui/ui-animation-core/api/current.txt b/ui/ui-animation-core/api/current.txt
index e1b1920..61912a7 100644
--- a/ui/ui-animation-core/api/current.txt
+++ b/ui/ui-animation-core/api/current.txt
@@ -2,9 +2,10 @@
package androidx.animation {
public final class AnimatedFloat extends androidx.animation.BaseAnimatedValue<java.lang.Float,androidx.animation.AnimationVector1D> {
- ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
- ctor public AnimatedFloat(float initVal);
- method public void doAnimationFrame$lintWithKotlin(long time);
+ ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedFloat(float initVal, androidx.animation.AnimationClockObservable clock);
+ ctor @Deprecated public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
+ method public void doAnimationFrame$lintWithKotlin(long timeMillis);
method public float getVelocity();
method public void setBounds(float min = Float.NEGATIVE_INFINITY, float max = Float.POSITIVE_INFINITY);
method public void snapTo(float targetValue);
@@ -12,7 +13,7 @@
}
public final class AnimatedValue<T, V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<T,V> {
- ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter);
+ ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter, androidx.animation.AnimationClockObservable clock);
method public V getVelocity();
property public final V velocity;
}
@@ -23,8 +24,8 @@
}
public final class AnimatedVectorValue<V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<V,V> {
- ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder);
- ctor public AnimatedVectorValue(V initVal);
+ ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedVectorValue(V initVal, androidx.animation.AnimationClockObservable clock);
}
public abstract class AnimationBuilder<T> {
diff --git a/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev04.txt b/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev04.txt
index e1b1920..61912a7 100644
--- a/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev04.txt
+++ b/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev04.txt
@@ -2,9 +2,10 @@
package androidx.animation {
public final class AnimatedFloat extends androidx.animation.BaseAnimatedValue<java.lang.Float,androidx.animation.AnimationVector1D> {
- ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
- ctor public AnimatedFloat(float initVal);
- method public void doAnimationFrame$lintWithKotlin(long time);
+ ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedFloat(float initVal, androidx.animation.AnimationClockObservable clock);
+ ctor @Deprecated public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
+ method public void doAnimationFrame$lintWithKotlin(long timeMillis);
method public float getVelocity();
method public void setBounds(float min = Float.NEGATIVE_INFINITY, float max = Float.POSITIVE_INFINITY);
method public void snapTo(float targetValue);
@@ -12,7 +13,7 @@
}
public final class AnimatedValue<T, V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<T,V> {
- ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter);
+ ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter, androidx.animation.AnimationClockObservable clock);
method public V getVelocity();
property public final V velocity;
}
@@ -23,8 +24,8 @@
}
public final class AnimatedVectorValue<V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<V,V> {
- ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder);
- ctor public AnimatedVectorValue(V initVal);
+ ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedVectorValue(V initVal, androidx.animation.AnimationClockObservable clock);
}
public abstract class AnimationBuilder<T> {
diff --git a/ui/ui-animation-core/api/public_plus_experimental_current.txt b/ui/ui-animation-core/api/public_plus_experimental_current.txt
index e1b1920..61912a7 100644
--- a/ui/ui-animation-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-animation-core/api/public_plus_experimental_current.txt
@@ -2,9 +2,10 @@
package androidx.animation {
public final class AnimatedFloat extends androidx.animation.BaseAnimatedValue<java.lang.Float,androidx.animation.AnimationVector1D> {
- ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
- ctor public AnimatedFloat(float initVal);
- method public void doAnimationFrame$lintWithKotlin(long time);
+ ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedFloat(float initVal, androidx.animation.AnimationClockObservable clock);
+ ctor @Deprecated public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
+ method public void doAnimationFrame$lintWithKotlin(long timeMillis);
method public float getVelocity();
method public void setBounds(float min = Float.NEGATIVE_INFINITY, float max = Float.POSITIVE_INFINITY);
method public void snapTo(float targetValue);
@@ -12,7 +13,7 @@
}
public final class AnimatedValue<T, V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<T,V> {
- ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter);
+ ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter, androidx.animation.AnimationClockObservable clock);
method public V getVelocity();
property public final V velocity;
}
@@ -23,8 +24,8 @@
}
public final class AnimatedVectorValue<V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<V,V> {
- ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder);
- ctor public AnimatedVectorValue(V initVal);
+ ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedVectorValue(V initVal, androidx.animation.AnimationClockObservable clock);
}
public abstract class AnimationBuilder<T> {
diff --git a/ui/ui-animation-core/api/restricted_0.1.0-dev04.txt b/ui/ui-animation-core/api/restricted_0.1.0-dev04.txt
index e1b1920..61912a7 100644
--- a/ui/ui-animation-core/api/restricted_0.1.0-dev04.txt
+++ b/ui/ui-animation-core/api/restricted_0.1.0-dev04.txt
@@ -2,9 +2,10 @@
package androidx.animation {
public final class AnimatedFloat extends androidx.animation.BaseAnimatedValue<java.lang.Float,androidx.animation.AnimationVector1D> {
- ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
- ctor public AnimatedFloat(float initVal);
- method public void doAnimationFrame$lintWithKotlin(long time);
+ ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedFloat(float initVal, androidx.animation.AnimationClockObservable clock);
+ ctor @Deprecated public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
+ method public void doAnimationFrame$lintWithKotlin(long timeMillis);
method public float getVelocity();
method public void setBounds(float min = Float.NEGATIVE_INFINITY, float max = Float.POSITIVE_INFINITY);
method public void snapTo(float targetValue);
@@ -12,7 +13,7 @@
}
public final class AnimatedValue<T, V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<T,V> {
- ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter);
+ ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter, androidx.animation.AnimationClockObservable clock);
method public V getVelocity();
property public final V velocity;
}
@@ -23,8 +24,8 @@
}
public final class AnimatedVectorValue<V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<V,V> {
- ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder);
- ctor public AnimatedVectorValue(V initVal);
+ ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedVectorValue(V initVal, androidx.animation.AnimationClockObservable clock);
}
public abstract class AnimationBuilder<T> {
diff --git a/ui/ui-animation-core/api/restricted_current.txt b/ui/ui-animation-core/api/restricted_current.txt
index e1b1920..61912a7 100644
--- a/ui/ui-animation-core/api/restricted_current.txt
+++ b/ui/ui-animation-core/api/restricted_current.txt
@@ -2,9 +2,10 @@
package androidx.animation {
public final class AnimatedFloat extends androidx.animation.BaseAnimatedValue<java.lang.Float,androidx.animation.AnimationVector1D> {
- ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
- ctor public AnimatedFloat(float initVal);
- method public void doAnimationFrame$lintWithKotlin(long time);
+ ctor public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedFloat(float initVal, androidx.animation.AnimationClockObservable clock);
+ ctor @Deprecated public AnimatedFloat(androidx.animation.ValueHolder<java.lang.Float> valueHolder);
+ method public void doAnimationFrame$lintWithKotlin(long timeMillis);
method public float getVelocity();
method public void setBounds(float min = Float.NEGATIVE_INFINITY, float max = Float.POSITIVE_INFINITY);
method public void snapTo(float targetValue);
@@ -12,7 +13,7 @@
}
public final class AnimatedValue<T, V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<T,V> {
- ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter);
+ ctor public AnimatedValue(androidx.animation.ValueHolder<T> valueHolder, androidx.animation.TwoWayConverter<T,V> typeConverter, androidx.animation.AnimationClockObservable clock);
method public V getVelocity();
property public final V velocity;
}
@@ -23,8 +24,8 @@
}
public final class AnimatedVectorValue<V extends androidx.animation.AnimationVector> extends androidx.animation.BaseAnimatedValue<V,V> {
- ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder);
- ctor public AnimatedVectorValue(V initVal);
+ ctor public AnimatedVectorValue(androidx.animation.ValueHolder<V> valueHolder, androidx.animation.AnimationClockObservable clock);
+ ctor public AnimatedVectorValue(V initVal, androidx.animation.AnimationClockObservable clock);
}
public abstract class AnimationBuilder<T> {
diff --git a/ui/ui-animation-core/src/main/java/androidx/animation/AnimatedValue.kt b/ui/ui-animation-core/src/main/java/androidx/animation/AnimatedValue.kt
index d5a1f17..df585f6 100644
--- a/ui/ui-animation-core/src/main/java/androidx/animation/AnimatedValue.kt
+++ b/ui/ui-animation-core/src/main/java/androidx/animation/AnimatedValue.kt
@@ -17,11 +17,9 @@
package androidx.animation
import android.util.Log
-import android.view.Choreographer
import androidx.animation.AnimationEndReason.BoundReached
import androidx.animation.AnimationEndReason.Interrupted
import androidx.animation.AnimationEndReason.TargetReached
-
/**
* This is the base class for [AnimatedValue]. It contains all the functionality of AnimatedValue.
* It is intended to be used as a base class for the other classes (such as [AnimatedFloat] to build
@@ -36,10 +34,12 @@
* @param typeConverter A two way type converter that converts from value to [AnimationVector1D],
* [AnimationVector2D], [AnimationVector3D], or [AnimationVector4D], and vice
* versa.
+ * @param clock An animation clock observable controlling the progression of the animated value
*/
sealed class BaseAnimatedValue<T, V : AnimationVector>(
private val valueHolder: ValueHolder<T>,
- typeConverter: TwoWayConverter<T, V>
+ internal val typeConverter: TwoWayConverter<T, V>,
+ private val clock: AnimationClockObservable
) {
/**
@@ -50,8 +50,9 @@
*/
constructor(
initVal: T,
- typeConverter: TwoWayConverter<T, V>
- ) : this(ValueHolder(initVal), typeConverter)
+ typeConverter: TwoWayConverter<T, V>,
+ clock: AnimationClockObservable
+ ) : this(ValueHolder(initVal), typeConverter, clock)
/**
* Current value of the animation.
@@ -81,7 +82,6 @@
*/
internal var velocityVector: V = typeConverter.createNewVector()
- internal val typeConverter: TwoWayConverter<T, V> = typeConverter
internal var onEnd: ((AnimationEndReason, T) -> Unit)? = null
private lateinit var anim: AnimationWrapper<T, V>
private var startTime: Long = Unset
@@ -89,10 +89,9 @@
// end of the animation.
private var lastFrameTime: Long = Unset
- private var frameCallback = object : Choreographer.FrameCallback {
- override fun doFrame(frameTimeNanos: Long) {
- // TODO: Refactor out all the dependencies on Choreographer
- doAnimationFrame(frameTimeNanos / 1000000L)
+ private var animationClockObserver = object : AnimationClockObserver {
+ override fun onAnimationFrame(frameTimeMillis: Long) {
+ doAnimationFrame(frameTimeMillis)
}
}
@@ -211,33 +210,27 @@
onEnd?.invoke(endReason, endValue)
}
- internal open fun doAnimationFrame(time: Long) {
+ internal open fun doAnimationFrame(timeMillis: Long) {
val playtime: Long
if (startTime == Unset) {
- startTime = time
+ startTime = timeMillis
playtime = 0
} else {
- playtime = time - startTime
+ playtime = timeMillis - startTime
}
- lastFrameTime = time
+ lastFrameTime = timeMillis
value = anim.getValue(playtime)
velocityVector = anim.getVelocity(playtime)
val animationFinished = anim.isFinished(playtime)
- if (!animationFinished) {
- Choreographer.getInstance().postFrameCallback(frameCallback)
- if (DEBUG) {
- Log.w(
- "AnimValue",
- "value = $value, playtime = $playtime, velocity: $velocityVector"
- )
- }
- } else {
- if (DEBUG) {
- Log.w("AnimValue", "value = $value, playtime = $playtime, animation finished")
- }
- endAnimation()
+ if (DEBUG) {
+ val debugLogMessage = if (animationFinished)
+ "value = $value, playtime = $playtime, animation finished"
+ else
+ "value = $value, playtime = $playtime, velocity: $velocityVector"
+ Log.w("AnimValue", debugLogMessage)
}
+ if (animationFinished) endAnimation()
}
internal fun startAnimation(anim: AnimationWrapper<T, V>) {
@@ -255,7 +248,7 @@
} else {
startTime = Unset
isRunning = true
- Choreographer.getInstance().postFrameCallback(frameCallback)
+ clock.subscribe(animationClockObserver)
}
if (DEBUG) {
Log.w("AnimValue", "start animation")
@@ -263,7 +256,7 @@
}
internal fun endAnimation(endReason: AnimationEndReason = TargetReached) {
- Choreographer.getInstance().removeFrameCallback(frameCallback)
+ clock.unsubscribe(animationClockObserver)
isRunning = false
startTime = Unset
lastFrameTime = Unset
@@ -288,17 +281,19 @@
*/
class AnimatedValue<T, V : AnimationVector>(
valueHolder: ValueHolder<T>,
- typeConverter: TwoWayConverter<T, V>
-) : BaseAnimatedValue<T, V>(valueHolder, typeConverter) {
+ typeConverter: TwoWayConverter<T, V>,
+ clock: AnimationClockObservable
+) : BaseAnimatedValue<T, V>(valueHolder, typeConverter, clock) {
val velocity: V
get() = velocityVector
}
// TODO class description
class AnimatedVectorValue<V : AnimationVector>(
- valueHolder: ValueHolder<V>
-) : BaseAnimatedValue<V, V>(valueHolder, valueHolder.value.createPassThroughConverter()) {
- constructor(initVal: V) : this(ValueHolder(initVal))
+ valueHolder: ValueHolder<V>,
+ clock: AnimationClockObservable
+) : BaseAnimatedValue<V, V>(valueHolder, valueHolder.value.createPassThroughConverter(), clock) {
+ constructor(initVal: V, clock: AnimationClockObservable) : this(ValueHolder(initVal), clock)
}
/**
@@ -309,11 +304,16 @@
*
* @param valueHolder A value holder of Float type whose value field will be updated during
* animations
+ * @param clock An animation clock observable controlling the progression of the animated value
*/
class AnimatedFloat(
- valueHolder: ValueHolder<Float>
-) : BaseAnimatedValue<Float, AnimationVector1D>(valueHolder, FloatToVectorConverter) {
- constructor(initVal: Float) : this(ValueHolder(initVal))
+ valueHolder: ValueHolder<Float>,
+ clock: AnimationClockObservable
+) : BaseAnimatedValue<Float, AnimationVector1D>(valueHolder, FloatToVectorConverter, clock) {
+ constructor(initVal: Float, clock: AnimationClockObservable) : this(ValueHolder(initVal), clock)
+
+ @Deprecated("This method is to support existing APIs not providing clocks.")
+ constructor(valueHolder: ValueHolder<Float>) : this(valueHolder, DefaultAnimationClock())
private var min: Float = Float.NEGATIVE_INFINITY
private var max: Float = Float.POSITIVE_INFINITY
@@ -339,8 +339,8 @@
super.snapTo(targetValue.coerceIn(min, max))
}
- override fun doAnimationFrame(time: Long) {
- super.doAnimationFrame(time)
+ override fun doAnimationFrame(timeMillis: Long) {
+ super.doAnimationFrame(timeMillis)
if (value < min) {
value = min
endAnimation(BoundReached)
diff --git a/ui/ui-animation-core/src/test/java/androidx/animation/AnimatedValueTest.kt b/ui/ui-animation-core/src/test/java/androidx/animation/AnimatedValueTest.kt
new file mode 100644
index 0000000..ea043bb
--- /dev/null
+++ b/ui/ui-animation-core/src/test/java/androidx/animation/AnimatedValueTest.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.animation
+
+import junit.framework.TestCase.assertEquals
+import junit.framework.TestCase.assertNotNull
+import junit.framework.TestCase.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class AnimatedValueTest {
+ private lateinit var clock: ManualAnimationClock
+
+ @Before
+ fun init() {
+ clock = ManualAnimationClock(0L)
+ }
+
+ @Test
+ fun testAnimation() {
+ val animatedFloat = AnimatedFloat(0f, clock)
+ animatedFloat.animateTo(1f)
+ clock.clockTimeMillis += 100000L
+ assertEquals(1f, animatedFloat.value, epsilon)
+ }
+
+ @Test
+ fun testInitialValue() {
+ val animatedFloat = AnimatedFloat(1.2f, clock)
+ animatedFloat.animateTo(100f)
+ assertEquals(1.2f, animatedFloat.value, epsilon)
+ }
+
+ @Test
+ fun testTargetValue() {
+ val animatedFloat = AnimatedFloat(0f, clock)
+ animatedFloat.animateTo(2f)
+ animatedFloat.animateTo(1.5f)
+ assertEquals(1.5f, animatedFloat.targetValue, epsilon)
+ }
+
+ @Test
+ fun testProgressionUp() {
+ val animatedFloat = AnimatedFloat(0f, clock)
+
+ animatedFloat.animateTo(1f)
+
+ clock.clockTimeMillis = 0L
+ val valueAtTimeZero = animatedFloat.value
+
+ clock.clockTimeMillis = 1L
+ val valueAtTimeOne = animatedFloat.value
+
+ assertTrue(valueAtTimeOne > valueAtTimeZero)
+ }
+
+ @Test
+ fun testProgressionDown() {
+ val animatedFloat = AnimatedFloat(0f, clock)
+
+ animatedFloat.animateTo(-1f)
+
+ clock.clockTimeMillis = 0L
+ val valueAtTimeZero = animatedFloat.value
+
+ clock.clockTimeMillis = 1L
+ val valueAtTimeOne = animatedFloat.value
+
+ assertTrue(valueAtTimeOne < valueAtTimeZero)
+ }
+
+ @Test
+ fun testEndCallback() {
+ val animatedFloat = AnimatedFloat(0f, clock)
+
+ var animationEndReason: AnimationEndReason? = null
+ var animationEndValue: Float? = null
+
+ animatedFloat.animateTo(1f) { reason, value ->
+ animationEndReason = reason
+ animationEndValue = value
+ }
+
+ clock.clockTimeMillis += 100000L
+
+ assertNotNull(animationEndValue)
+ assertNotNull(animationEndReason)
+
+ assertEquals(1f, animationEndValue!!, epsilon)
+ assertEquals(AnimationEndReason.TargetReached, animationEndReason)
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-animation-core/src/test/java/androidx/animation/TypeConverterTest.kt b/ui/ui-animation-core/src/test/java/androidx/animation/TypeConverterTest.kt
index 6a557f1..a145548 100644
--- a/ui/ui-animation-core/src/test/java/androidx/animation/TypeConverterTest.kt
+++ b/ui/ui-animation-core/src/test/java/androidx/animation/TypeConverterTest.kt
@@ -27,7 +27,7 @@
fun testFloatToVectorConverter() {
verifyFloatConverter(FloatToVectorConverter)
verifyFloatConverter(FloatPropKey().typeConverter)
- verifyFloatConverter(AnimatedFloat(5f).typeConverter)
+ verifyFloatConverter(AnimatedFloat(5f, ManualAnimationClock(0L)).typeConverter)
}
@Test
@@ -48,7 +48,7 @@
}
private fun <V : AnimationVector> verifyV2VConverter(value: V) {
- val converter = AnimatedVectorValue(value).typeConverter
+ val converter = AnimatedVectorValue(value, ManualAnimationClock(0L)).typeConverter
assertEquals(converter.convertFromVector(value), converter.convertToVector(value))
}
diff --git a/ui/ui-animation/api/0.1.0-dev04.txt b/ui/ui-animation/api/0.1.0-dev04.txt
index 2e5f447..7a78e4b 100644
--- a/ui/ui-animation/api/0.1.0-dev04.txt
+++ b/ui/ui-animation/api/0.1.0-dev04.txt
@@ -2,9 +2,9 @@
package androidx.ui.animation {
public final class AnimatedValueEffectsKt {
- method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal);
- method public static androidx.animation.AnimatedFloat animatedFloat(float initVal);
- method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter);
+ method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static androidx.animation.AnimatedFloat animatedFloat(float initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
}
public final class ColorPropKey implements androidx.animation.PropKey<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> {
diff --git a/ui/ui-animation/api/current.txt b/ui/ui-animation/api/current.txt
index 2e5f447..7a78e4b 100644
--- a/ui/ui-animation/api/current.txt
+++ b/ui/ui-animation/api/current.txt
@@ -2,9 +2,9 @@
package androidx.ui.animation {
public final class AnimatedValueEffectsKt {
- method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal);
- method public static androidx.animation.AnimatedFloat animatedFloat(float initVal);
- method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter);
+ method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static androidx.animation.AnimatedFloat animatedFloat(float initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
}
public final class ColorPropKey implements androidx.animation.PropKey<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> {
diff --git a/ui/ui-animation/api/public_plus_experimental_0.1.0-dev04.txt b/ui/ui-animation/api/public_plus_experimental_0.1.0-dev04.txt
index 2e5f447..7a78e4b 100644
--- a/ui/ui-animation/api/public_plus_experimental_0.1.0-dev04.txt
+++ b/ui/ui-animation/api/public_plus_experimental_0.1.0-dev04.txt
@@ -2,9 +2,9 @@
package androidx.ui.animation {
public final class AnimatedValueEffectsKt {
- method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal);
- method public static androidx.animation.AnimatedFloat animatedFloat(float initVal);
- method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter);
+ method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static androidx.animation.AnimatedFloat animatedFloat(float initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
}
public final class ColorPropKey implements androidx.animation.PropKey<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> {
diff --git a/ui/ui-animation/api/public_plus_experimental_current.txt b/ui/ui-animation/api/public_plus_experimental_current.txt
index 2e5f447..7a78e4b 100644
--- a/ui/ui-animation/api/public_plus_experimental_current.txt
+++ b/ui/ui-animation/api/public_plus_experimental_current.txt
@@ -2,9 +2,9 @@
package androidx.ui.animation {
public final class AnimatedValueEffectsKt {
- method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal);
- method public static androidx.animation.AnimatedFloat animatedFloat(float initVal);
- method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter);
+ method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static androidx.animation.AnimatedFloat animatedFloat(float initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
}
public final class ColorPropKey implements androidx.animation.PropKey<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> {
diff --git a/ui/ui-animation/api/restricted_0.1.0-dev04.txt b/ui/ui-animation/api/restricted_0.1.0-dev04.txt
index 2e5f447..7a78e4b 100644
--- a/ui/ui-animation/api/restricted_0.1.0-dev04.txt
+++ b/ui/ui-animation/api/restricted_0.1.0-dev04.txt
@@ -2,9 +2,9 @@
package androidx.ui.animation {
public final class AnimatedValueEffectsKt {
- method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal);
- method public static androidx.animation.AnimatedFloat animatedFloat(float initVal);
- method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter);
+ method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static androidx.animation.AnimatedFloat animatedFloat(float initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
}
public final class ColorPropKey implements androidx.animation.PropKey<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> {
diff --git a/ui/ui-animation/api/restricted_current.txt b/ui/ui-animation/api/restricted_current.txt
index 2e5f447..7a78e4b 100644
--- a/ui/ui-animation/api/restricted_current.txt
+++ b/ui/ui-animation/api/restricted_current.txt
@@ -2,9 +2,9 @@
package androidx.ui.animation {
public final class AnimatedValueEffectsKt {
- method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal);
- method public static androidx.animation.AnimatedFloat animatedFloat(float initVal);
- method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter);
+ method public static androidx.animation.AnimatedValue<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> animatedColor(androidx.ui.graphics.Color initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static androidx.animation.AnimatedFloat animatedFloat(float initVal, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
+ method public static <T, V extends androidx.animation.AnimationVector> androidx.animation.AnimatedValue<T,V> animatedValue(T? initVal, androidx.animation.TwoWayConverter<T,V> converter, androidx.animation.AnimationClockObservable clock = ambient(AnimationClockAmbient));
}
public final class ColorPropKey implements androidx.animation.PropKey<androidx.ui.graphics.Color,androidx.animation.AnimationVector4D> {
diff --git a/ui/ui-animation/src/main/java/androidx/ui/animation/AnimatedValueEffects.kt b/ui/ui-animation/src/main/java/androidx/ui/animation/AnimatedValueEffects.kt
index 2185bcd..26d3dae 100644
--- a/ui/ui-animation/src/main/java/androidx/ui/animation/AnimatedValueEffects.kt
+++ b/ui/ui-animation/src/main/java/androidx/ui/animation/AnimatedValueEffects.kt
@@ -18,13 +18,16 @@
import androidx.animation.AnimatedFloat
import androidx.animation.AnimatedValue
+import androidx.animation.AnimationClockObservable
import androidx.animation.TwoWayConverter
import androidx.compose.Model
import androidx.animation.ValueHolder
import androidx.animation.AnimationVector
import androidx.animation.AnimationVector4D
import androidx.compose.Composable
+import androidx.compose.ambient
import androidx.compose.remember
+import androidx.ui.core.AnimationClockAmbient
import androidx.ui.graphics.Color
/**
@@ -39,8 +42,9 @@
@Composable
fun <T, V : AnimationVector> animatedValue(
initVal: T,
- converter: TwoWayConverter<T, V>
-): AnimatedValue<T, V> = remember { AnimatedValue(AnimValueHolder(initVal), converter) }
+ converter: TwoWayConverter<T, V>,
+ clock: AnimationClockObservable = ambient(AnimationClockAmbient)
+): AnimatedValue<T, V> = remember { AnimatedValue(AnimValueHolder(initVal), converter, clock) }
/**
* The animatedValue effect creates an [AnimatedFloat] and positionally memoizes it. When the
@@ -50,8 +54,11 @@
* @param initVal Initial value to set [AnimatedFloat] to.
*/
@Composable
-fun animatedFloat(initVal: Float): AnimatedFloat =
- remember { AnimatedFloat(AnimValueHolder(initVal)) }
+fun animatedFloat(
+ initVal: Float,
+ clock: AnimationClockObservable = ambient(AnimationClockAmbient)
+): AnimatedFloat =
+ remember { AnimatedFloat(AnimValueHolder(initVal), clock) }
/**
* The animatedValue effect creates an [AnimatedValue] of [Color] and positionally memoizes it. When
@@ -61,10 +68,19 @@
* @param initVal Initial value to set [AnimatedValue] to.
*/
@Composable
-fun animatedColor(initVal: Color): AnimatedValue<Color, AnimationVector4D> =
- remember { AnimatedValue(AnimValueHolder(initVal), ColorToVectorConverter(initVal.colorSpace)) }
+fun animatedColor(
+ initVal: Color,
+ clock: AnimationClockObservable = ambient(AnimationClockAmbient)
+): AnimatedValue<Color, AnimationVector4D> =
+ remember {
+ AnimatedValue(
+ valueHolder = AnimValueHolder(initVal),
+ typeConverter = ColorToVectorConverter(initVal.colorSpace),
+ clock = clock
+ )
+ }
@Model
-private class AnimValueHolder<T> (
+private class AnimValueHolder<T>(
override var value: T
) : ValueHolder<T>
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/animation/AnimatedValueHolder.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/animation/AnimatedValueHolder.kt
index fd519f0..6390624 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/animation/AnimatedValueHolder.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/animation/AnimatedValueHolder.kt
@@ -33,6 +33,7 @@
@Model
class AnimatedValueHolder(initial: Float) : ValueHolder<Float> {
+ @Suppress("DEPRECATION")
val animatedFloat = AnimatedFloat(ListeneableValueHolder(initial, { value = it }))
/**