blob: 0106f7fbe70ed3ac189ef59fba57edabb2640875 [file] [log] [blame]
Chet Haasefaebd8f2012-05-18 14:17:57 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Chet Haase6ebe3de2013-06-17 16:50:50 -070016
Chet Haased82c8ac2013-08-26 14:20:16 -070017package android.transition;
Chet Haasefaebd8f2012-05-18 14:17:57 -070018
Chet Haased82c8ac2013-08-26 14:20:16 -070019import android.content.Context;
Chet Haasee9d32ea2013-06-04 08:46:42 -070020import android.util.ArrayMap;
Chet Haasec43524f2013-07-16 14:40:11 -070021import android.util.Log;
Chet Haasedf32aa82013-10-21 17:19:37 -070022import android.view.View;
Chet Haasefaebd8f2012-05-18 14:17:57 -070023import android.view.ViewGroup;
24import android.view.ViewTreeObserver;
25
Chet Haase7660d122013-09-13 13:29:31 -070026import java.lang.ref.WeakReference;
Chet Haase4f507232013-06-10 13:00:06 -070027import java.util.ArrayList;
28
Chet Haasefaebd8f2012-05-18 14:17:57 -070029/**
30 * This class manages the set of transitions that fire when there is a
31 * change of {@link Scene}. To use the manager, add scenes along with
32 * transition objects with calls to {@link #setTransition(Scene, Transition)}
33 * or {@link #setTransition(Scene, Scene, Transition)}. Setting specific
34 * transitions for scene changes is not required; by default, a Scene change
35 * will use {@link AutoTransition} to do something reasonable for most
36 * situations. Specifying other transitions for particular scene changes is
37 * only necessary if the application wants different transition behavior
38 * in these situations.
Chet Haased82c8ac2013-08-26 14:20:16 -070039 *
40 * <p>TransitionManagers can be declared in XML resource files inside the
41 * <code>res/transition</code> directory. TransitionManager resources consist of
42 * the <code>transitionManager</code>tag name, containing one or more
43 * <code>transition</code> tags, each of which describe the relationship of
44 * that transition to the from/to scene information in that tag.
45 * For example, here is a resource file that declares several scene
46 * transitions:</p>
47 *
48 * {@sample development/samples/ApiDemos/res/transition/transitions_mgr.xml TransitionManager}
49 *
50 * <p>For each of the <code>fromScene</code> and <code>toScene</code> attributes,
51 * there is a reference to a standard XML layout file. This is equivalent to
52 * creating a scene from a layout in code by calling
53 * {@link Scene#getSceneForLayout(ViewGroup, int, Context)}. For the
54 * <code>transition</code> attribute, there is a reference to a resource
55 * file in the <code>res/transition</code> directory which describes that
56 * transition.</p>
57 *
58 * Information on XML resource descriptions for transitions can be found for
59 * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet},
60 * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade},
61 * and {@link android.R.styleable#TransitionManager}.
Chet Haasefaebd8f2012-05-18 14:17:57 -070062 */
63public class TransitionManager {
64 // TODO: how to handle enter/exit?
65
Chet Haasec43524f2013-07-16 14:40:11 -070066 private static String LOG_TAG = "TransitionManager";
67
Chet Haased82c8ac2013-08-26 14:20:16 -070068 private static Transition sDefaultTransition = new AutoTransition();
Chet Haasefaebd8f2012-05-18 14:17:57 -070069
Adam Powellcfbe9be2013-11-06 14:58:58 -080070 private static final String[] EMPTY_STRINGS = new String[0];
71
Chet Haase08735182013-06-04 10:44:40 -070072 ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
73 ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
74 new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
Adam Powellcfbe9be2013-11-06 14:58:58 -080075 ArrayMap<Scene, ArrayMap<String, Transition>> mSceneNameTransitions =
76 new ArrayMap<Scene, ArrayMap<String, Transition>>();
77 ArrayMap<String, ArrayMap<Scene, Transition>> mNameSceneTransitions =
78 new ArrayMap<String, ArrayMap<Scene, Transition>>();
Chet Haase7660d122013-09-13 13:29:31 -070079 private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>
80 sRunningTransitions =
81 new ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>();
Chet Haase4f507232013-06-10 13:00:06 -070082 private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<ViewGroup>();
Chet Haasefaebd8f2012-05-18 14:17:57 -070083
Chet Haase4f507232013-06-10 13:00:06 -070084
85 /**
Chet Haasefaebd8f2012-05-18 14:17:57 -070086 * Sets the transition to be used for any scene change for which no
87 * other transition is explicitly set. The initial value is
88 * an {@link AutoTransition} instance.
89 *
90 * @param transition The default transition to be used for scene changes.
Adam Powell1e9f3d82013-10-24 18:54:33 -070091 *
92 * @hide pending later changes
Chet Haasefaebd8f2012-05-18 14:17:57 -070093 */
94 public void setDefaultTransition(Transition transition) {
Chet Haased82c8ac2013-08-26 14:20:16 -070095 sDefaultTransition = transition;
Chet Haasefaebd8f2012-05-18 14:17:57 -070096 }
97
98 /**
99 * Gets the current default transition. The initial value is an {@link
100 * AutoTransition} instance.
101 *
102 * @return The current default transition.
103 * @see #setDefaultTransition(Transition)
Adam Powell1e9f3d82013-10-24 18:54:33 -0700104 *
105 * @hide pending later changes
Chet Haasefaebd8f2012-05-18 14:17:57 -0700106 */
Chet Haased82c8ac2013-08-26 14:20:16 -0700107 public static Transition getDefaultTransition() {
108 return sDefaultTransition;
Chet Haasefaebd8f2012-05-18 14:17:57 -0700109 }
110
111 /**
112 * Sets a specific transition to occur when the given scene is entered.
113 *
114 * @param scene The scene which, when applied, will cause the given
115 * transition to run.
116 * @param transition The transition that will play when the given scene is
117 * entered. A value of null will result in the default behavior of
Adam Powell1e9f3d82013-10-24 18:54:33 -0700118 * using the default transition instead.
Chet Haasefaebd8f2012-05-18 14:17:57 -0700119 */
120 public void setTransition(Scene scene, Transition transition) {
121 mSceneTransitions.put(scene, transition);
122 }
123
124 /**
125 * Sets a specific transition to occur when the given pair of scenes is
126 * exited/entered.
127 *
128 * @param fromScene The scene being exited when the given transition will
129 * be run
130 * @param toScene The scene being entered when the given transition will
131 * be run
132 * @param transition The transition that will play when the given scene is
133 * entered. A value of null will result in the default behavior of
Adam Powell1e9f3d82013-10-24 18:54:33 -0700134 * using the default transition instead.
Chet Haasefaebd8f2012-05-18 14:17:57 -0700135 */
136 public void setTransition(Scene fromScene, Scene toScene, Transition transition) {
Chet Haase08735182013-06-04 10:44:40 -0700137 ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(toScene);
Chet Haasefaebd8f2012-05-18 14:17:57 -0700138 if (sceneTransitionMap == null) {
Chet Haase08735182013-06-04 10:44:40 -0700139 sceneTransitionMap = new ArrayMap<Scene, Transition>();
Chet Haasefaebd8f2012-05-18 14:17:57 -0700140 mScenePairTransitions.put(toScene, sceneTransitionMap);
141 }
142 sceneTransitionMap.put(fromScene, transition);
143 }
144
145 /**
146 * Returns the Transition for the given scene being entered. The result
147 * depends not only on the given scene, but also the scene which the
148 * {@link Scene#getSceneRoot() sceneRoot} of the Scene is currently in.
149 *
150 * @param scene The scene being entered
151 * @return The Transition to be used for the given scene change. If no
Adam Powell1e9f3d82013-10-24 18:54:33 -0700152 * Transition was specified for this scene change, the default transition
153 * will be used instead.
Chet Haasefaebd8f2012-05-18 14:17:57 -0700154 */
155 private Transition getTransition(Scene scene) {
156 Transition transition = null;
157 ViewGroup sceneRoot = scene.getSceneRoot();
158 if (sceneRoot != null) {
159 // TODO: cached in Scene instead? long-term, cache in View itself
Chet Haased82c8ac2013-08-26 14:20:16 -0700160 Scene currScene = Scene.getCurrentScene(sceneRoot);
Chet Haasefaebd8f2012-05-18 14:17:57 -0700161 if (currScene != null) {
Chet Haase08735182013-06-04 10:44:40 -0700162 ArrayMap<Scene, Transition> sceneTransitionMap = mScenePairTransitions.get(scene);
Chet Haasefaebd8f2012-05-18 14:17:57 -0700163 if (sceneTransitionMap != null) {
164 transition = sceneTransitionMap.get(currScene);
165 if (transition != null) {
166 return transition;
167 }
168 }
169 }
170 }
171 transition = mSceneTransitions.get(scene);
Chet Haased82c8ac2013-08-26 14:20:16 -0700172 return (transition != null) ? transition : sDefaultTransition;
Chet Haasefaebd8f2012-05-18 14:17:57 -0700173 }
174
175 /**
176 * This is where all of the work of a transition/scene-change is
177 * orchestrated. This method captures the start values for the given
178 * transition, exits the current Scene, enters the new scene, captures
179 * the end values for the transition, and finally plays the
180 * resulting values-populated transition.
181 *
182 * @param scene The scene being entered
183 * @param transition The transition to play for this scene change
184 */
Chet Haase6ebe3de2013-06-17 16:50:50 -0700185 private static void changeScene(Scene scene, Transition transition) {
Chet Haasefaebd8f2012-05-18 14:17:57 -0700186
187 final ViewGroup sceneRoot = scene.getSceneRoot();
188
Chet Haase6ebe3de2013-06-17 16:50:50 -0700189 Transition transitionClone = transition.clone();
190 transitionClone.setSceneRoot(sceneRoot);
191
Chet Haaseb7a7fc92013-09-20 16:33:08 -0700192 Scene oldScene = Scene.getCurrentScene(sceneRoot);
193 if (oldScene != null && oldScene.isCreatedFromLayoutResource()) {
194 transitionClone.setCanRemoveViews(true);
195 }
196
Chet Haase6ebe3de2013-06-17 16:50:50 -0700197 sceneChangeSetup(sceneRoot, transitionClone);
Chet Haasefaebd8f2012-05-18 14:17:57 -0700198
199 scene.enter();
200
Chet Haase6ebe3de2013-06-17 16:50:50 -0700201 sceneChangeRunTransition(sceneRoot, transitionClone);
Chet Haase4f507232013-06-10 13:00:06 -0700202 }
203
Chet Haase199acdf2013-07-24 18:40:55 -0700204 private static ArrayMap<ViewGroup, ArrayList<Transition>> getRunningTransitions() {
Chet Haase7660d122013-09-13 13:29:31 -0700205 WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>> runningTransitions =
Chet Haase199acdf2013-07-24 18:40:55 -0700206 sRunningTransitions.get();
Chet Haase7660d122013-09-13 13:29:31 -0700207 if (runningTransitions == null || runningTransitions.get() == null) {
208 ArrayMap<ViewGroup, ArrayList<Transition>> transitions =
209 new ArrayMap<ViewGroup, ArrayList<Transition>>();
210 runningTransitions = new WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>(
211 transitions);
Chet Haase199acdf2013-07-24 18:40:55 -0700212 sRunningTransitions.set(runningTransitions);
213 }
Chet Haase7660d122013-09-13 13:29:31 -0700214 return runningTransitions.get();
Chet Haase199acdf2013-07-24 18:40:55 -0700215 }
216
Chet Haase4f507232013-06-10 13:00:06 -0700217 private static void sceneChangeRunTransition(final ViewGroup sceneRoot,
218 final Transition transition) {
Chet Haasedf32aa82013-10-21 17:19:37 -0700219 if (transition != null && sceneRoot != null) {
220 MultiListener listener = new MultiListener(transition, sceneRoot);
221 sceneRoot.addOnAttachStateChangeListener(listener);
222 sceneRoot.getViewTreeObserver().addOnPreDrawListener(listener);
Chet Haasefaebd8f2012-05-18 14:17:57 -0700223 }
224 }
225
Chet Haasedf32aa82013-10-21 17:19:37 -0700226 /**
Adam Powellcfbe9be2013-11-06 14:58:58 -0800227 * Retrieve the transition from a named scene to a target defined scene if one has been
228 * associated with this TransitionManager.
229 *
230 * <p>A named scene is an indirect link for a transition. Fundamentally a named
231 * scene represents a potentially arbitrary intersection point of two otherwise independent
232 * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
233 * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
234 * In this way applications may define an API for more sophisticated transitions between
235 * caller and called activities very similar to the way that <code>Intent</code> extras
236 * define APIs for arguments and data propagation between activities.</p>
237 *
238 * @param fromName Named scene that this transition corresponds to
239 * @param toScene Target scene that this transition will move to
240 * @return Transition corresponding to the given fromName and toScene or null
241 * if no association exists in this TransitionManager
242 *
243 * @see #setTransition(String, Scene, Transition)
244 */
245 public Transition getNamedTransition(String fromName, Scene toScene) {
246 ArrayMap<Scene, Transition> m = mNameSceneTransitions.get(fromName);
247 if (m != null) {
248 return m.get(toScene);
249 }
250 return null;
251 }
252
253 /**
254 * Retrieve the transition from a defined scene to a target named scene if one has been
255 * associated with this TransitionManager.
256 *
257 * <p>A named scene is an indirect link for a transition. Fundamentally a named
258 * scene represents a potentially arbitrary intersection point of two otherwise independent
259 * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
260 * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
261 * In this way applications may define an API for more sophisticated transitions between
262 * caller and called activities very similar to the way that <code>Intent</code> extras
263 * define APIs for arguments and data propagation between activities.</p>
264 *
265 * @param fromScene Scene that this transition starts from
266 * @param toName Name of the target scene
267 * @return Transition corresponding to the given fromScene and toName or null
268 * if no association exists in this TransitionManager
269 */
270 public Transition getNamedTransition(Scene fromScene, String toName) {
271 ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
272 if (m != null) {
273 return m.get(toName);
274 }
275 return null;
276 }
277
278 /**
279 * Retrieve the supported target named scenes when transitioning away from the given scene.
280 *
281 * <p>A named scene is an indirect link for a transition. Fundamentally a named
282 * scene represents a potentially arbitrary intersection point of two otherwise independent
283 * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
284 * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
285 * In this way applications may define an API for more sophisticated transitions between
286 * caller and called activities very similar to the way that <code>Intent</code> extras
287 * define APIs for arguments and data propagation between activities.</p>
288 *
289 * @param fromScene Scene to transition from
290 * @return An array of Strings naming each supported transition starting from
291 * <code>fromScene</code>. If no transitions to a named scene from the given
292 * scene are supported this function will return a String[] of length 0.
293 *
294 * @see #setTransition(Scene, String, Transition)
295 */
296 public String[] getTargetSceneNames(Scene fromScene) {
297 final ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
298 if (m == null) {
299 return EMPTY_STRINGS;
300 }
301 final int count = m.size();
302 final String[] result = new String[count];
303 for (int i = 0; i < count; i++) {
304 result[i] = m.keyAt(i);
305 }
306 return result;
307 }
308
309 /**
310 * Set a transition from a specific scene to a named scene.
311 *
312 * <p>A named scene is an indirect link for a transition. Fundamentally a named
313 * scene represents a potentially arbitrary intersection point of two otherwise independent
314 * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
315 * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
316 * In this way applications may define an API for more sophisticated transitions between
317 * caller and called activities very similar to the way that <code>Intent</code> extras
318 * define APIs for arguments and data propagation between activities.</p>
319 *
320 * @param fromScene Scene to transition from
321 * @param toName Named scene to transition to
322 * @param transition Transition to use
323 *
324 * @see #getTargetSceneNames(Scene)
325 */
326 public void setTransition(Scene fromScene, String toName, Transition transition) {
327 ArrayMap<String, Transition> m = mSceneNameTransitions.get(fromScene);
328 if (m == null) {
329 m = new ArrayMap<String, Transition>();
330 mSceneNameTransitions.put(fromScene, m);
331 }
332 m.put(toName, transition);
333 }
334
335 /**
336 * Set a transition from a named scene to a concrete scene.
337 *
338 * <p>A named scene is an indirect link for a transition. Fundamentally a named
339 * scene represents a potentially arbitrary intersection point of two otherwise independent
340 * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO"
341 * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y.
342 * In this way applications may define an API for more sophisticated transitions between
343 * caller and called activities very similar to the way that <code>Intent</code> extras
344 * define APIs for arguments and data propagation between activities.</p>
345 *
346 * @param fromName Named scene to transition from
347 * @param toScene Scene to transition to
348 * @param transition Transition to use
349 *
350 * @see #getNamedTransition(String, Scene)
351 */
352 public void setTransition(String fromName, Scene toScene, Transition transition) {
353 ArrayMap<Scene, Transition> m = mNameSceneTransitions.get(fromName);
354 if (m == null) {
355 m = new ArrayMap<Scene, Transition>();
356 mNameSceneTransitions.put(fromName, m);
357 }
358 m.put(toScene, transition);
359 }
360
361 /**
Chet Haasedf32aa82013-10-21 17:19:37 -0700362 * This private utility class is used to listen for both OnPreDraw and
363 * OnAttachStateChange events. OnPreDraw events are the main ones we care
364 * about since that's what triggers the transition to take place.
365 * OnAttachStateChange events are also important in case the view is removed
366 * from the hierarchy before the OnPreDraw event takes place; it's used to
367 * clean up things since the OnPreDraw listener didn't get called in time.
368 */
369 private static class MultiListener implements ViewTreeObserver.OnPreDrawListener,
370 View.OnAttachStateChangeListener {
371
372 Transition mTransition;
373 ViewGroup mSceneRoot;
374
375 MultiListener(Transition transition, ViewGroup sceneRoot) {
376 mTransition = transition;
377 mSceneRoot = sceneRoot;
378 }
379
380 private void removeListeners() {
381 mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
382 mSceneRoot.removeOnAttachStateChangeListener(this);
383 }
384
385 @Override
386 public void onViewAttachedToWindow(View v) {
387 }
388
389 @Override
390 public void onViewDetachedFromWindow(View v) {
391 removeListeners();
392
393 sPendingTransitions.remove(mSceneRoot);
394 ArrayList<Transition> runningTransitions = getRunningTransitions().get(mSceneRoot);
395 if (runningTransitions != null && runningTransitions.size() > 0) {
396 for (Transition runningTransition : runningTransitions) {
397 runningTransition.resume();
398 }
399 }
400 mTransition.clearValues(true);
401 }
402
403 @Override
404 public boolean onPreDraw() {
405 removeListeners();
406 sPendingTransitions.remove(mSceneRoot);
407 // Add to running list, handle end to remove it
408 final ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions =
409 getRunningTransitions();
410 ArrayList<Transition> currentTransitions = runningTransitions.get(mSceneRoot);
411 ArrayList<Transition> previousRunningTransitions = null;
412 if (currentTransitions == null) {
413 currentTransitions = new ArrayList<Transition>();
414 runningTransitions.put(mSceneRoot, currentTransitions);
415 } else if (currentTransitions.size() > 0) {
416 previousRunningTransitions = new ArrayList<Transition>(currentTransitions);
417 }
418 currentTransitions.add(mTransition);
419 mTransition.addListener(new Transition.TransitionListenerAdapter() {
420 @Override
421 public void onTransitionEnd(Transition transition) {
422 ArrayList<Transition> currentTransitions =
423 runningTransitions.get(mSceneRoot);
424 currentTransitions.remove(transition);
425 }
426 });
427 mTransition.captureValues(mSceneRoot, false);
428 if (previousRunningTransitions != null) {
429 for (Transition runningTransition : previousRunningTransitions) {
430 runningTransition.resume();
431 }
432 }
433 mTransition.playTransition(mSceneRoot);
434
435 return true;
436 }
437 };
438
Chet Haase4f507232013-06-10 13:00:06 -0700439 private static void sceneChangeSetup(ViewGroup sceneRoot, Transition transition) {
440
Chet Haase4f507232013-06-10 13:00:06 -0700441 // Capture current values
Chet Haase199acdf2013-07-24 18:40:55 -0700442 ArrayList<Transition> runningTransitions = getRunningTransitions().get(sceneRoot);
443
444 if (runningTransitions != null && runningTransitions.size() > 0) {
445 for (Transition runningTransition : runningTransitions) {
446 runningTransition.pause();
447 }
448 }
Chet Haasec81a8492013-07-12 12:54:38 -0700449
Chet Haase4f507232013-06-10 13:00:06 -0700450 if (transition != null) {
451 transition.captureValues(sceneRoot, true);
452 }
453
454 // Notify previous scene that it is being exited
Chet Haased82c8ac2013-08-26 14:20:16 -0700455 Scene previousScene = Scene.getCurrentScene(sceneRoot);
Chet Haase4f507232013-06-10 13:00:06 -0700456 if (previousScene != null) {
457 previousScene.exit();
458 }
459 }
460
Chet Haasefaebd8f2012-05-18 14:17:57 -0700461 /**
462 * Change to the given scene, using the
463 * appropriate transition for this particular scene change
464 * (as specified to the TransitionManager, or the default
465 * if no such transition exists).
466 *
467 * @param scene The Scene to change to
468 */
469 public void transitionTo(Scene scene) {
470 // Auto transition if there is no transition declared for the Scene, but there is
471 // a root or parent view
472 changeScene(scene, getTransition(scene));
Chet Haasefaebd8f2012-05-18 14:17:57 -0700473 }
474
475 /**
Chet Haased82c8ac2013-08-26 14:20:16 -0700476 * Convenience method to simply change to the given scene using
Chet Haasefaebd8f2012-05-18 14:17:57 -0700477 * the default transition for TransitionManager.
478 *
479 * @param scene The Scene to change to
480 */
481 public static void go(Scene scene) {
482 changeScene(scene, sDefaultTransition);
483 }
484
485 /**
Chet Haased82c8ac2013-08-26 14:20:16 -0700486 * Convenience method to simply change to the given scene using
Chet Haasefaebd8f2012-05-18 14:17:57 -0700487 * the given transition.
488 *
489 * <p>Passing in <code>null</code> for the transition parameter will
490 * result in the scene changing without any transition running, and is
491 * equivalent to calling {@link Scene#exit()} on the scene root's
Chet Haased82c8ac2013-08-26 14:20:16 -0700492 * current scene, followed by {@link Scene#enter()} on the scene
493 * specified by the <code>scene</code> parameter.</p>
Chet Haasefaebd8f2012-05-18 14:17:57 -0700494 *
495 * @param scene The Scene to change to
496 * @param transition The transition to use for this scene change. A
497 * value of null causes the scene change to happen with no transition.
498 */
499 public static void go(Scene scene, Transition transition) {
500 changeScene(scene, transition);
501 }
502
503 /**
Chet Haased82c8ac2013-08-26 14:20:16 -0700504 * Convenience method to animate, using the default transition,
505 * to a new scene defined by all changes within the given scene root between
506 * calling this method and the next rendering frame.
507 * Equivalent to calling {@link #beginDelayedTransition(ViewGroup, Transition)}
508 * with a value of <code>null</code> for the <code>transition</code> parameter.
Chet Haasefaebd8f2012-05-18 14:17:57 -0700509 *
510 * @param sceneRoot The root of the View hierarchy to run the transition on.
Chet Haasefaebd8f2012-05-18 14:17:57 -0700511 */
Chet Haased82c8ac2013-08-26 14:20:16 -0700512 public static void beginDelayedTransition(final ViewGroup sceneRoot) {
513 beginDelayedTransition(sceneRoot, null);
Chet Haasefaebd8f2012-05-18 14:17:57 -0700514 }
Chet Haase4f507232013-06-10 13:00:06 -0700515
516 /**
Chet Haased82c8ac2013-08-26 14:20:16 -0700517 * Convenience method to animate to a new scene defined by all changes within
Chet Haase4f507232013-06-10 13:00:06 -0700518 * the given scene root between calling this method and the next rendering frame.
519 * Calling this method causes TransitionManager to capture current values in the
520 * scene root and then post a request to run a transition on the next frame.
521 * At that time, the new values in the scene root will be captured and changes
522 * will be animated. There is no need to create a Scene; it is implied by
523 * changes which take place between calling this method and the next frame when
524 * the transition begins.
525 *
526 * <p>Calling this method several times before the next frame (for example, if
527 * unrelated code also wants to make dynamic changes and run a transition on
528 * the same scene root), only the first call will trigger capturing values
529 * and exiting the current scene. Subsequent calls to the method with the
530 * same scene root during the same frame will be ignored.</p>
531 *
532 * <p>Passing in <code>null</code> for the transition parameter will
533 * cause the TransitionManager to use its default transition.</p>
534 *
535 * @param sceneRoot The root of the View hierarchy to run the transition on.
536 * @param transition The transition to use for this change. A
537 * value of null causes the TransitionManager to use the default transition.
538 */
539 public static void beginDelayedTransition(final ViewGroup sceneRoot, Transition transition) {
Chet Haase23c61f62013-09-14 11:28:46 -0700540 if (!sPendingTransitions.contains(sceneRoot) && sceneRoot.isLaidOut()) {
541 if (Transition.DBG) {
542 Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " +
543 sceneRoot + ", " + transition);
544 }
545 sPendingTransitions.add(sceneRoot);
546 if (transition == null) {
547 transition = sDefaultTransition;
548 }
549 final Transition transitionClone = transition.clone();
550 sceneChangeSetup(sceneRoot, transitionClone);
551 Scene.setCurrentScene(sceneRoot, null);
552 sceneChangeRunTransition(sceneRoot, transitionClone);
553 }
Chet Haase4f507232013-06-10 13:00:06 -0700554 }
Chet Haasefaebd8f2012-05-18 14:17:57 -0700555}