summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/view/transition/TransitionManager.java89
1 files changed, 73 insertions, 16 deletions
diff --git a/core/java/android/view/transition/TransitionManager.java b/core/java/android/view/transition/TransitionManager.java
index 4971a92466b3..8088f6b2c23d 100644
--- a/core/java/android/view/transition/TransitionManager.java
+++ b/core/java/android/view/transition/TransitionManager.java
@@ -19,6 +19,8 @@ import android.util.ArrayMap;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
+import java.util.ArrayList;
+
/**
* This class manages the set of transitions that fire when there is a
* change of {@link Scene}. To use the manager, add scenes along with
@@ -41,8 +43,10 @@ public class TransitionManager {
new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
static ArrayMap<ViewGroup, Transition> sRunningTransitions =
new ArrayMap<ViewGroup, Transition>();
+ private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<ViewGroup>();
+
- /**
+ /**
* Sets the transition to be used for any scene change for which no
* other transition is explicitly set. The initial value is
* an {@link AutoTransition} instance.
@@ -142,24 +146,15 @@ public class TransitionManager {
final ViewGroup sceneRoot = scene.getSceneRoot();
- Transition runningTransition = sRunningTransitions.get(sceneRoot);
- if (runningTransition != null) {
- runningTransition.cancelTransition();
- }
-
- // Capture current values
- if (transition != null) {
- transition.captureValues(sceneRoot, true);
- }
-
- // Notify previous scene that it is being exited
- Scene previousScene = sceneRoot.getCurrentScene();
- if (previousScene != null) {
- previousScene.exit();
- }
+ sceneChangeSetup(sceneRoot, transition);
scene.enter();
+ sceneChangeRunTransition(sceneRoot, transition);
+ }
+
+ private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
+ final Transition transition) {
if (transition != null) {
final ViewTreeObserver observer = sceneRoot.getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@@ -181,6 +176,25 @@ public class TransitionManager {
}
}
+ private static void sceneChangeSetup(ViewGroup sceneRoot, Transition transition) {
+
+ Transition runningTransition = sRunningTransitions.get(sceneRoot);
+ if (runningTransition != null) {
+ runningTransition.cancelTransition();
+ }
+
+ // Capture current values
+ if (transition != null) {
+ transition.captureValues(sceneRoot, true);
+ }
+
+ // Notify previous scene that it is being exited
+ Scene previousScene = sceneRoot.getCurrentScene();
+ if (previousScene != null) {
+ previousScene.exit();
+ }
+ }
+
/**
* Change to the given scene, using the
* appropriate transition for this particular scene change
@@ -272,4 +286,47 @@ public class TransitionManager {
scene.setEnterAction(action);
changeScene(scene, transition);
}
+
+ /**
+ * Static utility method to animate to a new scene defined by all changes within
+ * the given scene root between calling this method and the next rendering frame.
+ * Calling this method causes TransitionManager to capture current values in the
+ * scene root and then post a request to run a transition on the next frame.
+ * At that time, the new values in the scene root will be captured and changes
+ * will be animated. There is no need to create a Scene; it is implied by
+ * changes which take place between calling this method and the next frame when
+ * the transition begins.
+ *
+ * <p>Calling this method several times before the next frame (for example, if
+ * unrelated code also wants to make dynamic changes and run a transition on
+ * the same scene root), only the first call will trigger capturing values
+ * and exiting the current scene. Subsequent calls to the method with the
+ * same scene root during the same frame will be ignored.</p>
+ *
+ * <p>Passing in <code>null</code> for the transition parameter will
+ * cause the TransitionManager to use its default transition.</p>
+ *
+ * @param sceneRoot The root of the View hierarchy to run the transition on.
+ * @param transition The transition to use for this change. A
+ * value of null causes the TransitionManager to use the default transition.
+ */
+ public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) {
+
+ if (!sPendingTransitions.contains(sceneRoot)) {
+ sPendingTransitions.add(sceneRoot);
+ if (transition == null) {
+ transition = sDefaultTransition;
+ }
+ final Transition finalTransition = transition;
+ sceneChangeSetup(sceneRoot, transition);
+ sceneRoot.setCurrentScene(null);
+ sceneRoot.postOnAnimation(new Runnable() {
+ @Override
+ public void run() {
+ sPendingTransitions.remove(sceneRoot);
+ sceneChangeRunTransition(sceneRoot, finalTransition);
+ }
+ });
+ }
+ }
}