1c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki/* 2c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Copyright (C) 2016 The Android Open Source Project 3c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 4c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Licensed under the Apache License, Version 2.0 (the "License"); 5c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * you may not use this file except in compliance with the License. 6c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * You may obtain a copy of the License at 7c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 8c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * http://www.apache.org/licenses/LICENSE-2.0 9c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 10c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Unless required by applicable law or agreed to in writing, software 11c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * distributed under the License is distributed on an "AS IS" BASIS, 12c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * See the License for the specific language governing permissions and 14c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * limitations under the License. 15c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 16c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 17c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakipackage android.support.transition; 18c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 19c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport android.support.annotation.RestrictTo; 20c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakiimport android.support.v4.util.ArrayMap; 21c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakiimport android.support.v4.view.ViewCompat; 22c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakiimport android.util.Log; 23c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakiimport android.view.View; 24c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakiimport android.view.ViewGroup; 25c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakiimport android.view.ViewTreeObserver; 26c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 27c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakiimport java.lang.ref.WeakReference; 28c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakiimport java.util.ArrayList; 29c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 30c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viveretteimport static android.support.annotation.RestrictTo.Scope.GROUP_ID; 31c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette 32c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakiclass TransitionManagerPort { 33c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki // TODO: how to handle enter/exit? 34c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 35c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private static final String[] EMPTY_STRINGS = new String[0]; 36c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 37c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private static String LOG_TAG = "TransitionManager"; 38c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 39c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private static TransitionPort sDefaultTransition = new AutoTransitionPort(); 40c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 41c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<TransitionPort>>>> 42c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sRunningTransitions = new ThreadLocal<>(); 43c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 445bc71ed43cf5336547217c932a5fc5cbb8c618f5Aurimas Liutikas static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<>(); 45c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 46c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<ScenePort, TransitionPort> mSceneTransitions = new ArrayMap<>(); 47c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 48c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<ScenePort, ArrayMap<ScenePort, TransitionPort>> mScenePairTransitions = 49c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki new ArrayMap<>(); 50c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 51c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<ScenePort, ArrayMap<String, TransitionPort>> mSceneNameTransitions = new ArrayMap<>(); 52c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 53c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<String, ArrayMap<ScenePort, TransitionPort>> mNameSceneTransitions = new ArrayMap<>(); 54c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 55c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 56c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Gets the current default transition. The initial value is an {@link 57c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * AutoTransition} instance. 58c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 59c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @return The current default transition. 60c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @hide pending later changes 61c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @see #setDefaultTransition(TransitionPort) 62c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 63c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette @RestrictTo(GROUP_ID) 64c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public static TransitionPort getDefaultTransition() { 65c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return sDefaultTransition; 66c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 67c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 68c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 69c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Sets the transition to be used for any scene change for which no 70c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * other transition is explicitly set. The initial value is 71c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * an {@link AutoTransition} instance. 72c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 73c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param transition The default transition to be used for scene changes. 74c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @hide pending later changes 75c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 76c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette @RestrictTo(GROUP_ID) 77c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public void setDefaultTransition(TransitionPort transition) { 78c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sDefaultTransition = transition; 79c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 80c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 81c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 82c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * This is where all of the work of a transition/scene-change is 83c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * orchestrated. This method captures the start values for the given 84c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * transition, exits the current Scene, enters the new scene, captures 85c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * the end values for the transition, and finally plays the 86c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * resulting values-populated transition. 87c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 88c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param scene The scene being entered 89c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param transition The transition to play for this scene change 90c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 91c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private static void changeScene(ScenePort scene, TransitionPort transition) { 92c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 93c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki final ViewGroup sceneRoot = scene.getSceneRoot(); 94c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 95cbba0a52f7d7b593dbb13a138515f066f75cce80Yuichi Araki TransitionPort transitionClone = null; 96cbba0a52f7d7b593dbb13a138515f066f75cce80Yuichi Araki if (transition != null) { 97cbba0a52f7d7b593dbb13a138515f066f75cce80Yuichi Araki transitionClone = transition.clone(); 98cbba0a52f7d7b593dbb13a138515f066f75cce80Yuichi Araki transitionClone.setSceneRoot(sceneRoot); 99cbba0a52f7d7b593dbb13a138515f066f75cce80Yuichi Araki } 100c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 101c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ScenePort oldScene = ScenePort.getCurrentScene(sceneRoot); 102c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (oldScene != null && oldScene.isCreatedFromLayoutResource()) { 103c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki transitionClone.setCanRemoveViews(true); 104c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 105c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 106c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sceneChangeSetup(sceneRoot, transitionClone); 107c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 108c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki scene.enter(); 109c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 110c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sceneChangeRunTransition(sceneRoot, transitionClone); 111c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 112c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 1135bc71ed43cf5336547217c932a5fc5cbb8c618f5Aurimas Liutikas static ArrayMap<ViewGroup, ArrayList<TransitionPort>> getRunningTransitions() { 114c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki WeakReference<ArrayMap<ViewGroup, ArrayList<TransitionPort>>> runningTransitions = 115c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sRunningTransitions.get(); 116c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (runningTransitions == null || runningTransitions.get() == null) { 117c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<ViewGroup, ArrayList<TransitionPort>> transitions = new ArrayMap<>(); 118c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki runningTransitions = new WeakReference<>(transitions); 119c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sRunningTransitions.set(runningTransitions); 120c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 121c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return runningTransitions.get(); 122c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 123c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 124c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private static void sceneChangeRunTransition(final ViewGroup sceneRoot, 125c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki final TransitionPort transition) { 126c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (transition != null && sceneRoot != null) { 127c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki MultiListener listener = new MultiListener(transition, sceneRoot); 128c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sceneRoot.addOnAttachStateChangeListener(listener); 129c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sceneRoot.getViewTreeObserver().addOnPreDrawListener(listener); 130c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 131c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 132c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 133c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private static void sceneChangeSetup(ViewGroup sceneRoot, TransitionPort transition) { 134c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 135c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki // Capture current values 136c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayList<TransitionPort> runningTransitions = getRunningTransitions().get(sceneRoot); 137c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 138c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (runningTransitions != null && runningTransitions.size() > 0) { 139c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki for (TransitionPort runningTransition : runningTransitions) { 140feda490114a23e64dba591f1e2589723a1a12660Yuichi Araki runningTransition.pause(sceneRoot); 141c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 142c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 143c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 144c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (transition != null) { 145c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki transition.captureValues(sceneRoot, true); 146c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 147c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 148c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki // Notify previous scene that it is being exited 149c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ScenePort previousScene = ScenePort.getCurrentScene(sceneRoot); 150c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (previousScene != null) { 151c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki previousScene.exit(); 152c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 153c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 154c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 155c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public static void go(ScenePort scene) { 156c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki changeScene(scene, sDefaultTransition); 157c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 158c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 159c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public static void go(ScenePort scene, TransitionPort transition) { 160c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki changeScene(scene, transition); 161c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 162c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 163c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public static void beginDelayedTransition(final ViewGroup sceneRoot) { 164c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki beginDelayedTransition(sceneRoot, null); 165c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 166c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 167c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public static void beginDelayedTransition(final ViewGroup sceneRoot, 168c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki TransitionPort transition) { 169c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (!sPendingTransitions.contains(sceneRoot) && ViewCompat.isLaidOut(sceneRoot)) { 170c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (TransitionPort.DBG) { 171c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki Log.d(LOG_TAG, "beginDelayedTransition: root, transition = " + 172c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sceneRoot + ", " + transition); 173c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 174c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sPendingTransitions.add(sceneRoot); 175c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (transition == null) { 176c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki transition = sDefaultTransition; 177c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 178c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki final TransitionPort transitionClone = transition.clone(); 179c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sceneChangeSetup(sceneRoot, transitionClone); 180c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ScenePort.setCurrentScene(sceneRoot, null); 181c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sceneChangeRunTransition(sceneRoot, transitionClone); 182c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 183c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 184c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 185c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public void setTransition(ScenePort scene, TransitionPort transition) { 186c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mSceneTransitions.put(scene, transition); 187c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 188c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 189c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public void setTransition(ScenePort fromScene, ScenePort toScene, TransitionPort transition) { 190c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<ScenePort, TransitionPort> sceneTransitionMap = mScenePairTransitions.get(toScene); 191c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (sceneTransitionMap == null) { 192c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sceneTransitionMap = new ArrayMap<>(); 193c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mScenePairTransitions.put(toScene, sceneTransitionMap); 194c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 195c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sceneTransitionMap.put(fromScene, transition); 196c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 197c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 198c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 199c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Returns the Transition for the given scene being entered. The result 200c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * depends not only on the given scene, but also the scene which the 201c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * {@link ScenePort#getSceneRoot() sceneRoot} of the Scene is currently in. 202c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 203c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param scene The scene being entered 204c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @return The Transition to be used for the given scene change. If no 205c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Transition was specified for this scene change, the default transition 206c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * will be used instead. 207c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 208c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private TransitionPort getTransition(ScenePort scene) { 209c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki TransitionPort transition; 210c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ViewGroup sceneRoot = scene.getSceneRoot(); 211c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (sceneRoot != null) { 212c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki // TODO: cached in Scene instead? long-term, cache in View itself 213c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ScenePort currScene = ScenePort.getCurrentScene(sceneRoot); 214c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (currScene != null) { 215c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<ScenePort, TransitionPort> sceneTransitionMap = mScenePairTransitions 216c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki .get(scene); 217c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (sceneTransitionMap != null) { 218c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki transition = sceneTransitionMap.get(currScene); 219c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (transition != null) { 220c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return transition; 221c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 222c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 223c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 224c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 225c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki transition = mSceneTransitions.get(scene); 226c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return (transition != null) ? transition : sDefaultTransition; 227c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 228c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 229c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 230c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Retrieve the transition from a named scene to a target defined scene if one has been 231c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * associated with this TransitionManager. 232c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 233c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * <p>A named scene is an indirect link for a transition. Fundamentally a named 234c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * scene represents a potentially arbitrary intersection point of two otherwise independent 235c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO" 236c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y. 237c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * In this way applications may define an API for more sophisticated transitions between 238c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * caller and called activities very similar to the way that <code>Intent</code> extras 239c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * define APIs for arguments and data propagation between activities.</p> 240c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 241c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param fromName Named scene that this transition corresponds to 242c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param toScene Target scene that this transition will move to 243c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @return Transition corresponding to the given fromName and toScene or null 244c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * if no association exists in this TransitionManager 245c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @see #setTransition(String, ScenePort, TransitionPort) 246c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 247c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public TransitionPort getNamedTransition(String fromName, ScenePort toScene) { 248c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<ScenePort, TransitionPort> m = mNameSceneTransitions.get(fromName); 249c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (m != null) { 250c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return m.get(toScene); 251c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 252c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return null; 253c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 254c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 255c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ; 256c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 257c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 258c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Retrieve the transition from a defined scene to a target named scene if one has been 259c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * associated with this TransitionManager. 260c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 261c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * <p>A named scene is an indirect link for a transition. Fundamentally a named 262c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * scene represents a potentially arbitrary intersection point of two otherwise independent 263c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO" 264c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y. 265c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * In this way applications may define an API for more sophisticated transitions between 266c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * caller and called activities very similar to the way that <code>Intent</code> extras 267c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * define APIs for arguments and data propagation between activities.</p> 268c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 269c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param fromScene Scene that this transition starts from 270c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param toName Name of the target scene 271c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @return Transition corresponding to the given fromScene and toName or null 272c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * if no association exists in this TransitionManager 273c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 274c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public TransitionPort getNamedTransition(ScenePort fromScene, String toName) { 275c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<String, TransitionPort> m = mSceneNameTransitions.get(fromScene); 276c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (m != null) { 277c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return m.get(toName); 278c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 279c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return null; 280c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 281c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 282c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 283c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Retrieve the supported target named scenes when transitioning away from the given scene. 284c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 285c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * <p>A named scene is an indirect link for a transition. Fundamentally a named 286c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * scene represents a potentially arbitrary intersection point of two otherwise independent 287c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO" 288c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y. 289c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * In this way applications may define an API for more sophisticated transitions between 290c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * caller and called activities very similar to the way that <code>Intent</code> extras 291c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * define APIs for arguments and data propagation between activities.</p> 292c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 293c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param fromScene Scene to transition from 294c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @return An array of Strings naming each supported transition starting from 295c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * <code>fromScene</code>. If no transitions to a named scene from the given 296c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * scene are supported this function will return a String[] of length 0. 297c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @see #setTransition(ScenePort, String, TransitionPort) 298c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 299c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public String[] getTargetSceneNames(ScenePort fromScene) { 300c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki final ArrayMap<String, TransitionPort> m = mSceneNameTransitions.get(fromScene); 301c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (m == null) { 302c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return EMPTY_STRINGS; 303c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 304c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki final int count = m.size(); 305c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki final String[] result = new String[count]; 306c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki for (int i = 0; i < count; i++) { 307c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki result[i] = m.keyAt(i); 308c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 309c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return result; 310c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 311c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 312c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 313c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Set a transition from a specific scene to a named scene. 314c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 315c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * <p>A named scene is an indirect link for a transition. Fundamentally a named 316c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * scene represents a potentially arbitrary intersection point of two otherwise independent 317c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO" 318c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y. 319c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * In this way applications may define an API for more sophisticated transitions between 320c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * caller and called activities very similar to the way that <code>Intent</code> extras 321c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * define APIs for arguments and data propagation between activities.</p> 322c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 323c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param fromScene Scene to transition from 324c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param toName Named scene to transition to 325c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param transition Transition to use 326c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @see #getTargetSceneNames(ScenePort) 327c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 328c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public void setTransition(ScenePort fromScene, String toName, TransitionPort transition) { 329c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<String, TransitionPort> m = mSceneNameTransitions.get(fromScene); 330c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (m == null) { 331c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki m = new ArrayMap<>(); 332c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mSceneNameTransitions.put(fromScene, m); 333c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 334c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki m.put(toName, transition); 335c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 336c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 337c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 338c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Set a transition from a named scene to a concrete scene. 339c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 340c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * <p>A named scene is an indirect link for a transition. Fundamentally a named 341c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * scene represents a potentially arbitrary intersection point of two otherwise independent 342c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * transitions. Activity A may define a transition from scene X to "com.example.scene.FOO" 343c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * while activity B may define a transition from scene "com.example.scene.FOO" to scene Y. 344c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * In this way applications may define an API for more sophisticated transitions between 345c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * caller and called activities very similar to the way that <code>Intent</code> extras 346c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * define APIs for arguments and data propagation between activities.</p> 347c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * 348c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param fromName Named scene to transition from 349c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param toScene Scene to transition to 350c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @param transition Transition to use 351c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * @see #getNamedTransition(String, ScenePort) 352c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 353c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public void setTransition(String fromName, ScenePort toScene, TransitionPort transition) { 354c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayMap<ScenePort, TransitionPort> m = mNameSceneTransitions.get(fromName); 355c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (m == null) { 356c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki m = new ArrayMap<>(); 357c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mNameSceneTransitions.put(fromName, m); 358c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 359c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki m.put(toScene, transition); 360c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 361c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 362c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public void transitionTo(ScenePort scene) { 363c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki // Auto transition if there is no transition declared for the Scene, but there is 364c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki // a root or parent view 365c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki changeScene(scene, getTransition(scene)); 366c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 367c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 368c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki /** 369c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * This private utility class is used to listen for both OnPreDraw and 370c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * OnAttachStateChange events. OnPreDraw events are the main ones we care 371c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * about since that's what triggers the transition to take place. 372c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * OnAttachStateChange events are also important in case the view is removed 373c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * from the hierarchy before the OnPreDraw event takes place; it's used to 374c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * clean up things since the OnPreDraw listener didn't get called in time. 375c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */ 376c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private static class MultiListener implements ViewTreeObserver.OnPreDrawListener, 377c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki View.OnAttachStateChangeListener { 378c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 379c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki TransitionPort mTransition; 380c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 381c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ViewGroup mSceneRoot; 382c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 383c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki MultiListener(TransitionPort transition, ViewGroup sceneRoot) { 384c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mTransition = transition; 385c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mSceneRoot = sceneRoot; 386c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 387c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 388c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki private void removeListeners() { 389c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mSceneRoot.getViewTreeObserver().removeOnPreDrawListener(this); 390c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mSceneRoot.removeOnAttachStateChangeListener(this); 391c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 392c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 393c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki @Override 394c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public void onViewAttachedToWindow(View v) { 395c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 396c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 397c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki @Override 398c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public void onViewDetachedFromWindow(View v) { 399c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki removeListeners(); 400c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 401c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sPendingTransitions.remove(mSceneRoot); 402c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayList<TransitionPort> runningTransitions = getRunningTransitions().get(mSceneRoot); 403c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (runningTransitions != null && runningTransitions.size() > 0) { 404c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki for (TransitionPort runningTransition : runningTransitions) { 405feda490114a23e64dba591f1e2589723a1a12660Yuichi Araki runningTransition.resume(mSceneRoot); 406c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 407c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 408c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mTransition.clearValues(true); 409c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 410c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 411c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki @Override 412c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public boolean onPreDraw() { 413c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki removeListeners(); 414c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki sPendingTransitions.remove(mSceneRoot); 415c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki // Add to running list, handle end to remove it 416c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki final ArrayMap<ViewGroup, ArrayList<TransitionPort>> runningTransitions = 417c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki getRunningTransitions(); 418c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayList<TransitionPort> currentTransitions = runningTransitions.get(mSceneRoot); 419c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayList<TransitionPort> previousRunningTransitions = null; 420c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (currentTransitions == null) { 421c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki currentTransitions = new ArrayList<>(); 422c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki runningTransitions.put(mSceneRoot, currentTransitions); 423c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } else if (currentTransitions.size() > 0) { 424c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki previousRunningTransitions = new ArrayList<>(currentTransitions); 425c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 426c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki currentTransitions.add(mTransition); 427c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mTransition.addListener(new TransitionPort.TransitionListenerAdapter() { 428c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki @Override 429c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki public void onTransitionEnd(TransitionPort transition) { 430c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki ArrayList<TransitionPort> currentTransitions = 431c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki runningTransitions.get(mSceneRoot); 432c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki currentTransitions.remove(transition); 433c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 434c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki }); 435c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mTransition.captureValues(mSceneRoot, false); 436c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki if (previousRunningTransitions != null) { 437c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki for (TransitionPort runningTransition : previousRunningTransitions) { 438feda490114a23e64dba591f1e2589723a1a12660Yuichi Araki runningTransition.resume(mSceneRoot); 439c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 440c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 441c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki mTransition.playTransition(mSceneRoot); 442c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki 443c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki return true; 444c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 445c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki } 446c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki} 447