[go: nahoru, domu]

Add listener to transition composable

Also use the first state passed into transition composable as the
default state.

BUG: 144683881
BUG: 144061469

Test: included in the CL
Change-Id: I443c754e4079b0826736dae51e4337ad458051e2
diff --git a/ui/ui-animation-core/api/0.1.0-dev03.txt b/ui/ui-animation-core/api/0.1.0-dev03.txt
index f627e70..227080e 100644
--- a/ui/ui-animation-core/api/0.1.0-dev03.txt
+++ b/ui/ui-animation-core/api/0.1.0-dev03.txt
@@ -240,7 +240,7 @@
   }
 
   public final class TransitionAnimation<T> implements androidx.animation.TransitionState {
-    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock);
+    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock, T? initState);
     method public operator <T> T! get(androidx.animation.PropKey<T> propKey);
     method public kotlin.jvm.functions.Function1<T,kotlin.Unit>? getOnStateChangeFinished();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnUpdate();
@@ -255,8 +255,6 @@
 
   public final class TransitionDefinition<T> {
     ctor public TransitionDefinition();
-    method public androidx.animation.TransitionAnimation<T> createAnimation();
-    method public androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.AnimationClockObservable clock);
     method public androidx.animation.TransitionState getStateFor(T? name);
     method public void snapTransition(kotlin.Pair<? extends T,? extends T>![] fromToPairs, T? nextState = null);
     method public void state(T? name, kotlin.jvm.functions.Function1<? super androidx.animation.MutableTransitionState,kotlin.Unit> init);
@@ -266,6 +264,8 @@
 
   public final class TransitionDefinitionKt {
     ctor public TransitionDefinitionKt();
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>);
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>, androidx.animation.AnimationClockObservable clock, T? initState = null);
     method public static <T> androidx.animation.TransitionDefinition<T> transitionDefinition(kotlin.jvm.functions.Function1<? super androidx.animation.TransitionDefinition<T>,kotlin.Unit> init);
   }
 
diff --git a/ui/ui-animation-core/api/current.txt b/ui/ui-animation-core/api/current.txt
index f627e70..227080e 100644
--- a/ui/ui-animation-core/api/current.txt
+++ b/ui/ui-animation-core/api/current.txt
@@ -240,7 +240,7 @@
   }
 
   public final class TransitionAnimation<T> implements androidx.animation.TransitionState {
-    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock);
+    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock, T? initState);
     method public operator <T> T! get(androidx.animation.PropKey<T> propKey);
     method public kotlin.jvm.functions.Function1<T,kotlin.Unit>? getOnStateChangeFinished();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnUpdate();
@@ -255,8 +255,6 @@
 
   public final class TransitionDefinition<T> {
     ctor public TransitionDefinition();
-    method public androidx.animation.TransitionAnimation<T> createAnimation();
-    method public androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.AnimationClockObservable clock);
     method public androidx.animation.TransitionState getStateFor(T? name);
     method public void snapTransition(kotlin.Pair<? extends T,? extends T>![] fromToPairs, T? nextState = null);
     method public void state(T? name, kotlin.jvm.functions.Function1<? super androidx.animation.MutableTransitionState,kotlin.Unit> init);
@@ -266,6 +264,8 @@
 
   public final class TransitionDefinitionKt {
     ctor public TransitionDefinitionKt();
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>);
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>, androidx.animation.AnimationClockObservable clock, T? initState = null);
     method public static <T> androidx.animation.TransitionDefinition<T> transitionDefinition(kotlin.jvm.functions.Function1<? super androidx.animation.TransitionDefinition<T>,kotlin.Unit> init);
   }
 
diff --git a/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev03.txt
index f627e70..227080e 100644
--- a/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev03.txt
@@ -240,7 +240,7 @@
   }
 
   public final class TransitionAnimation<T> implements androidx.animation.TransitionState {
-    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock);
+    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock, T? initState);
     method public operator <T> T! get(androidx.animation.PropKey<T> propKey);
     method public kotlin.jvm.functions.Function1<T,kotlin.Unit>? getOnStateChangeFinished();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnUpdate();
@@ -255,8 +255,6 @@
 
   public final class TransitionDefinition<T> {
     ctor public TransitionDefinition();
-    method public androidx.animation.TransitionAnimation<T> createAnimation();
-    method public androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.AnimationClockObservable clock);
     method public androidx.animation.TransitionState getStateFor(T? name);
     method public void snapTransition(kotlin.Pair<? extends T,? extends T>![] fromToPairs, T? nextState = null);
     method public void state(T? name, kotlin.jvm.functions.Function1<? super androidx.animation.MutableTransitionState,kotlin.Unit> init);
@@ -266,6 +264,8 @@
 
   public final class TransitionDefinitionKt {
     ctor public TransitionDefinitionKt();
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>);
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>, androidx.animation.AnimationClockObservable clock, T? initState = null);
     method public static <T> androidx.animation.TransitionDefinition<T> transitionDefinition(kotlin.jvm.functions.Function1<? super androidx.animation.TransitionDefinition<T>,kotlin.Unit> init);
   }
 
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 f627e70..227080e 100644
--- a/ui/ui-animation-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-animation-core/api/public_plus_experimental_current.txt
@@ -240,7 +240,7 @@
   }
 
   public final class TransitionAnimation<T> implements androidx.animation.TransitionState {
-    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock);
+    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock, T? initState);
     method public operator <T> T! get(androidx.animation.PropKey<T> propKey);
     method public kotlin.jvm.functions.Function1<T,kotlin.Unit>? getOnStateChangeFinished();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnUpdate();
@@ -255,8 +255,6 @@
 
   public final class TransitionDefinition<T> {
     ctor public TransitionDefinition();
-    method public androidx.animation.TransitionAnimation<T> createAnimation();
-    method public androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.AnimationClockObservable clock);
     method public androidx.animation.TransitionState getStateFor(T? name);
     method public void snapTransition(kotlin.Pair<? extends T,? extends T>![] fromToPairs, T? nextState = null);
     method public void state(T? name, kotlin.jvm.functions.Function1<? super androidx.animation.MutableTransitionState,kotlin.Unit> init);
@@ -266,6 +264,8 @@
 
   public final class TransitionDefinitionKt {
     ctor public TransitionDefinitionKt();
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>);
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>, androidx.animation.AnimationClockObservable clock, T? initState = null);
     method public static <T> androidx.animation.TransitionDefinition<T> transitionDefinition(kotlin.jvm.functions.Function1<? super androidx.animation.TransitionDefinition<T>,kotlin.Unit> init);
   }
 
diff --git a/ui/ui-animation-core/api/restricted_0.1.0-dev03.txt b/ui/ui-animation-core/api/restricted_0.1.0-dev03.txt
index f627e70..227080e 100644
--- a/ui/ui-animation-core/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-animation-core/api/restricted_0.1.0-dev03.txt
@@ -240,7 +240,7 @@
   }
 
   public final class TransitionAnimation<T> implements androidx.animation.TransitionState {
-    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock);
+    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock, T? initState);
     method public operator <T> T! get(androidx.animation.PropKey<T> propKey);
     method public kotlin.jvm.functions.Function1<T,kotlin.Unit>? getOnStateChangeFinished();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnUpdate();
@@ -255,8 +255,6 @@
 
   public final class TransitionDefinition<T> {
     ctor public TransitionDefinition();
-    method public androidx.animation.TransitionAnimation<T> createAnimation();
-    method public androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.AnimationClockObservable clock);
     method public androidx.animation.TransitionState getStateFor(T? name);
     method public void snapTransition(kotlin.Pair<? extends T,? extends T>![] fromToPairs, T? nextState = null);
     method public void state(T? name, kotlin.jvm.functions.Function1<? super androidx.animation.MutableTransitionState,kotlin.Unit> init);
@@ -266,6 +264,8 @@
 
   public final class TransitionDefinitionKt {
     ctor public TransitionDefinitionKt();
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>);
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>, androidx.animation.AnimationClockObservable clock, T? initState = null);
     method public static <T> androidx.animation.TransitionDefinition<T> transitionDefinition(kotlin.jvm.functions.Function1<? super androidx.animation.TransitionDefinition<T>,kotlin.Unit> init);
   }
 
diff --git a/ui/ui-animation-core/api/restricted_current.txt b/ui/ui-animation-core/api/restricted_current.txt
index f627e70..227080e 100644
--- a/ui/ui-animation-core/api/restricted_current.txt
+++ b/ui/ui-animation-core/api/restricted_current.txt
@@ -240,7 +240,7 @@
   }
 
   public final class TransitionAnimation<T> implements androidx.animation.TransitionState {
-    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock);
+    ctor public TransitionAnimation(androidx.animation.TransitionDefinition<T> def, androidx.animation.AnimationClockObservable clock, T? initState);
     method public operator <T> T! get(androidx.animation.PropKey<T> propKey);
     method public kotlin.jvm.functions.Function1<T,kotlin.Unit>? getOnStateChangeFinished();
     method public kotlin.jvm.functions.Function0<kotlin.Unit>? getOnUpdate();
@@ -255,8 +255,6 @@
 
   public final class TransitionDefinition<T> {
     ctor public TransitionDefinition();
-    method public androidx.animation.TransitionAnimation<T> createAnimation();
-    method public androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.AnimationClockObservable clock);
     method public androidx.animation.TransitionState getStateFor(T? name);
     method public void snapTransition(kotlin.Pair<? extends T,? extends T>![] fromToPairs, T? nextState = null);
     method public void state(T? name, kotlin.jvm.functions.Function1<? super androidx.animation.MutableTransitionState,kotlin.Unit> init);
@@ -266,6 +264,8 @@
 
   public final class TransitionDefinitionKt {
     ctor public TransitionDefinitionKt();
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>);
+    method public static <T> androidx.animation.TransitionAnimation<T> createAnimation(androidx.animation.TransitionDefinition<T>, androidx.animation.AnimationClockObservable clock, T? initState = null);
     method public static <T> androidx.animation.TransitionDefinition<T> transitionDefinition(kotlin.jvm.functions.Function1<? super androidx.animation.TransitionDefinition<T>,kotlin.Unit> init);
   }
 
diff --git a/ui/ui-animation-core/src/main/java/androidx/animation/TransitionAnimation.kt b/ui/ui-animation-core/src/main/java/androidx/animation/TransitionAnimation.kt
index 974895c..cfa72b5 100644
--- a/ui/ui-animation-core/src/main/java/androidx/animation/TransitionAnimation.kt
+++ b/ui/ui-animation-core/src/main/java/androidx/animation/TransitionAnimation.kt
@@ -35,7 +35,8 @@
  */
 class TransitionAnimation<T> (
     private val def: TransitionDefinition<T>,
-    private val clock: AnimationClockObservable
+    private val clock: AnimationClockObservable,
+    initState: T? = null
 ) : TransitionState {
 
     var onUpdate: (() -> Unit)? = null
@@ -61,10 +62,17 @@
     // TODO("Create a more efficient code path for default only transition def")
 
     init {
-        currentState = AnimationState(def.defaultState, def.defaultState.name)
+        // If an initial state is specified in the ctor, use that instead of the default state.
+        val defaultState: StateImpl<T>
+        if (initState == null) {
+            defaultState = def.defaultState
+        } else {
+            defaultState = def.states[initState]!!
+        }
+        currentState = AnimationState(defaultState, defaultState.name)
         // Need to come up with a better plan to avoid the foot gun of accidentally modifying state
-        fromState = def.defaultState
-        toState = def.defaultState
+        fromState = defaultState
+        toState = defaultState
     }
 
     // Interpolate current state and the new state
@@ -96,13 +104,14 @@
             // props in each state.
         }
 
-        startAnimation()
-
         fromState = AnimationState(currentState, toState.name)
         toState = newState
         if (DEBUG) {
             Log.w("TransAnim", "Animating to new state: ${toState.name}")
         }
+
+        // Start animation should be called after all the setup has been done
+        startAnimation()
     }
 
     private fun getPlayTime(): Long {
diff --git a/ui/ui-animation-core/src/main/java/androidx/animation/TransitionDefinition.kt b/ui/ui-animation-core/src/main/java/androidx/animation/TransitionDefinition.kt
index b903e3d..48162a8 100644
--- a/ui/ui-animation-core/src/main/java/androidx/animation/TransitionDefinition.kt
+++ b/ui/ui-animation-core/src/main/java/androidx/animation/TransitionDefinition.kt
@@ -198,18 +198,6 @@
     }
 
     /**
-     * Creates a transition animation using the transition definition.
-     */
-    fun createAnimation() = TransitionAnimation(this, DefaultAnimationClock())
-
-    /**
-     * Creates a transition animation using the transition definition and the given clock.
-     *
-     * @param clock The clock source for animation to get frame time from.
-     */
-    fun createAnimation(clock: AnimationClockObservable) = TransitionAnimation(this, clock)
-
-    /**
      * Returns a state holder for the specific state [name]. Useful for the cases
      * where we don't need actual animation to be happening like in tests.
      */
@@ -217,6 +205,23 @@
 }
 
 /**
+ * Creates a transition animation using the transition definition.
+ * // TODO: Ripple impl needs to pass the ambient here clock, then we can remove this function.
+ */
+fun <T> TransitionDefinition<T>.createAnimation() =
+    TransitionAnimation(this, DefaultAnimationClock())
+
+/**
+ * Creates a transition animation using the transition definition and the given clock.
+ *
+ * @param clock The clock source for animation to get frame time from.
+ */
+fun <T> TransitionDefinition<T>.createAnimation(
+    clock: AnimationClockObservable,
+    initState: T? = null
+) = TransitionAnimation(this, clock, initState)
+
+/**
  * Creates a [TransitionDefinition] using the [init] function to initialize it.
  *
  * @param init Initialization function for the [TransitionDefinition]
diff --git a/ui/ui-animation-core/src/test/java/androidx/animation/TransitionAnimationTest.kt b/ui/ui-animation-core/src/test/java/androidx/animation/TransitionAnimationTest.kt
index bdfb631..a151099 100644
--- a/ui/ui-animation-core/src/test/java/androidx/animation/TransitionAnimationTest.kt
+++ b/ui/ui-animation-core/src/test/java/androidx/animation/TransitionAnimationTest.kt
@@ -28,7 +28,7 @@
         val clock = ManualAnimationClock(0)
         val anim = TransitionAnimation(def1, clock)
         anim.toState(AnimState.B)
-        val physicsAnim = Physics<Float>()
+        val physicsAnim = SpringAnimation<Float>()
         var playTime = 0L
         do {
             // Increment the time stamp until the animation finishes
@@ -43,6 +43,33 @@
             playTime += 20L
         } while (anim.isRunning)
     }
+
+    @Test
+    fun testInitialState() {
+        val clock = ManualAnimationClock(0)
+        val anim = TransitionAnimation(def1, clock, AnimState.C)
+        assertEquals(anim[prop1], 1000f)
+        assertEquals(anim[prop2], -250f)
+    }
+
+    @Test
+    fun testStateChangedListener() {
+        val clock = ManualAnimationClock(0)
+        val anim = TransitionAnimation(def1, clock, AnimState.C)
+        var lastState: AnimState? = null
+        anim.>
+            lastState = it
+        }
+        anim.toState(AnimState.A)
+        // Increment the clock by some large amount to guarantee the finish of the animation
+        clock.clockTimeMillis += 100000
+        assertEquals(AnimState.A, lastState)
+
+        anim.toState(AnimState.B)
+        // Increment the clock by some large amount to guarantee the finish of the animation
+        clock.clockTimeMillis += 100000
+        assertEquals(AnimState.B, lastState)
+    }
 }
 
 private enum class AnimState {
@@ -62,4 +89,9 @@
         this[prop1] = 1f
         this[prop2] = -100f
     }
+
+    state(AnimState.C) {
+        this[prop1] = 1000f
+        this[prop2] = -250f
+    }
 }
\ No newline at end of file
diff --git a/ui/ui-animation/api/0.1.0-dev03.txt b/ui/ui-animation/api/0.1.0-dev03.txt
index 113f0be..e1311a3 100644
--- a/ui/ui-animation/api/0.1.0-dev03.txt
+++ b/ui/ui-animation/api/0.1.0-dev03.txt
@@ -35,7 +35,7 @@
 
   public final class TransitionKt {
     ctor public TransitionKt();
-    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>?  kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
     method public static boolean getTransitionsEnabled();
     method public static void setTransitionsEnabled(boolean p);
   }
diff --git a/ui/ui-animation/api/current.txt b/ui/ui-animation/api/current.txt
index 113f0be..e1311a3 100644
--- a/ui/ui-animation/api/current.txt
+++ b/ui/ui-animation/api/current.txt
@@ -35,7 +35,7 @@
 
   public final class TransitionKt {
     ctor public TransitionKt();
-    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>?  kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
     method public static boolean getTransitionsEnabled();
     method public static void setTransitionsEnabled(boolean p);
   }
diff --git a/ui/ui-animation/api/public_plus_experimental_0.1.0-dev03.txt b/ui/ui-animation/api/public_plus_experimental_0.1.0-dev03.txt
index 113f0be..e1311a3 100644
--- a/ui/ui-animation/api/public_plus_experimental_0.1.0-dev03.txt
+++ b/ui/ui-animation/api/public_plus_experimental_0.1.0-dev03.txt
@@ -35,7 +35,7 @@
 
   public final class TransitionKt {
     ctor public TransitionKt();
-    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>?  kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
     method public static boolean getTransitionsEnabled();
     method public static void setTransitionsEnabled(boolean p);
   }
diff --git a/ui/ui-animation/api/public_plus_experimental_current.txt b/ui/ui-animation/api/public_plus_experimental_current.txt
index 113f0be..e1311a3 100644
--- a/ui/ui-animation/api/public_plus_experimental_current.txt
+++ b/ui/ui-animation/api/public_plus_experimental_current.txt
@@ -35,7 +35,7 @@
 
   public final class TransitionKt {
     ctor public TransitionKt();
-    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>?  kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
     method public static boolean getTransitionsEnabled();
     method public static void setTransitionsEnabled(boolean p);
   }
diff --git a/ui/ui-animation/api/restricted_0.1.0-dev03.txt b/ui/ui-animation/api/restricted_0.1.0-dev03.txt
index 113f0be..e1311a3 100644
--- a/ui/ui-animation/api/restricted_0.1.0-dev03.txt
+++ b/ui/ui-animation/api/restricted_0.1.0-dev03.txt
@@ -35,7 +35,7 @@
 
   public final class TransitionKt {
     ctor public TransitionKt();
-    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>?  kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
     method public static boolean getTransitionsEnabled();
     method public static void setTransitionsEnabled(boolean p);
   }
diff --git a/ui/ui-animation/api/restricted_current.txt b/ui/ui-animation/api/restricted_current.txt
index 113f0be..e1311a3 100644
--- a/ui/ui-animation/api/restricted_current.txt
+++ b/ui/ui-animation/api/restricted_current.txt
@@ -35,7 +35,7 @@
 
   public final class TransitionKt {
     ctor public TransitionKt();
-    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
+    method public static <T> void Transition(androidx.animation.TransitionDefinition<T> definition, T? toState, androidx.animation.AnimationClockObservable clock = +ambient(AnimationClockAmbient), kotlin.jvm.functions.Function1<? super T,kotlin.Unit>?  kotlin.jvm.functions.Function1<? super androidx.animation.TransitionState,kotlin.Unit> children);
     method public static boolean getTransitionsEnabled();
     method public static void setTransitionsEnabled(boolean p);
   }
diff --git a/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt b/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
index 24cc90d..fe609ff 100644
--- a/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
+++ b/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
@@ -21,6 +21,7 @@
 import androidx.animation.TransitionAnimation
 import androidx.animation.TransitionDefinition
 import androidx.animation.TransitionState
+import androidx.animation.createAnimation
 import androidx.compose.Composable
 import androidx.compose.Model
 import androidx.compose.ambient
@@ -38,11 +39,13 @@
     definition: TransitionDefinition<T>,
     toState: T,
     clock: AnimationClockObservable = +ambient(AnimationClockAmbient),
+    onStateChangeFinished: ((T) -> Unit)? = null,
     children: @Composable() (state: TransitionState) -> Unit
 ) {
     if (transitionsEnabled) {
         // TODO: This null is workaround for b/132148894
-        val model = +memo(definition, null) { TransitionModel(definition, clock) }
+        val model = +memo(definition, null) { TransitionModel(definition, toState, clock) }
+        model.anim.>
         model.anim.toState(toState)
         children(model)
     } else {
@@ -61,12 +64,13 @@
 @Model
 private class TransitionModel<T>(
     transitionDef: TransitionDefinition<T>,
+    initState: T,
     clock: AnimationClockObservable
 ) : TransitionState {
 
     private var animationPulse = 0L
     internal val anim: TransitionAnimation<T> =
-        transitionDef.createAnimation(clock).apply {
+        transitionDef.createAnimation(clock, initState).apply {
             >
                 animationPulse++
             }
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/ripple/DefaultRippleEffect.kt b/ui/ui-material/src/main/java/androidx/ui/material/ripple/DefaultRippleEffect.kt
index d93a99d..9a766e6 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/ripple/DefaultRippleEffect.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/ripple/DefaultRippleEffect.kt
@@ -21,6 +21,7 @@
 import androidx.animation.InterruptionHandling
 import androidx.animation.LinearEasing
 import androidx.animation.TransitionAnimation
+import androidx.animation.createAnimation
 import androidx.animation.transitionDefinition
 import androidx.ui.animation.PxPositionPropKey
 import androidx.ui.animation.PxPropKey