14500be62dea3895a98336122a2944cc4ab024bc5George Mount/* 24500be62dea3895a98336122a2944cc4ab024bc5George Mount * Copyright (C) 2014 The Android Open Source Project 34500be62dea3895a98336122a2944cc4ab024bc5George Mount * 44500be62dea3895a98336122a2944cc4ab024bc5George Mount * Licensed under the Apache License, Version 2.0 (the "License"); 54500be62dea3895a98336122a2944cc4ab024bc5George Mount * you may not use this file except in compliance with the License. 64500be62dea3895a98336122a2944cc4ab024bc5George Mount * You may obtain a copy of the License at 74500be62dea3895a98336122a2944cc4ab024bc5George Mount * 84500be62dea3895a98336122a2944cc4ab024bc5George Mount * http://www.apache.org/licenses/LICENSE-2.0 94500be62dea3895a98336122a2944cc4ab024bc5George Mount * 104500be62dea3895a98336122a2944cc4ab024bc5George Mount * Unless required by applicable law or agreed to in writing, software 114500be62dea3895a98336122a2944cc4ab024bc5George Mount * distributed under the License is distributed on an "AS IS" BASIS, 124500be62dea3895a98336122a2944cc4ab024bc5George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134500be62dea3895a98336122a2944cc4ab024bc5George Mount * See the License for the specific language governing permissions and 144500be62dea3895a98336122a2944cc4ab024bc5George Mount * limitations under the License. 154500be62dea3895a98336122a2944cc4ab024bc5George Mount */ 164500be62dea3895a98336122a2944cc4ab024bc5George Mount 174500be62dea3895a98336122a2944cc4ab024bc5George Mountpackage android.support.v4.app; 184500be62dea3895a98336122a2944cc4ab024bc5George Mount 199f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mountimport android.graphics.Rect; 208f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viveretteimport android.support.annotation.RequiresApi; 219f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mountimport android.transition.Transition; 229f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mountimport android.transition.TransitionManager; 239f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mountimport android.transition.TransitionSet; 244500be62dea3895a98336122a2944cc4ab024bc5George Mountimport android.view.View; 254500be62dea3895a98336122a2944cc4ab024bc5George Mountimport android.view.ViewGroup; 264500be62dea3895a98336122a2944cc4ab024bc5George Mount 274500be62dea3895a98336122a2944cc4ab024bc5George Mountimport java.util.ArrayList; 28c766ad5a6e0c115f08b933ede22375c7070a3391George Mountimport java.util.List; 299f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mountimport java.util.Map; 304500be62dea3895a98336122a2944cc4ab024bc5George Mount 318f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viverette@RequiresApi(21) 324500be62dea3895a98336122a2944cc4ab024bc5George Mountclass FragmentTransitionCompat21 { 334500be62dea3895a98336122a2944cc4ab024bc5George Mount 34990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 35990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Returns a clone of a transition or null if it is null 36990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 370f5ae57910484f1d873fdad90966b6244a633bd4George Mount public static Object cloneTransition(Object transition) { 38990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Transition copy = null; 390f5ae57910484f1d873fdad90966b6244a633bd4George Mount if (transition != null) { 40990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount copy = ((Transition) transition).clone(); 414500be62dea3895a98336122a2944cc4ab024bc5George Mount } 42990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return copy; 434500be62dea3895a98336122a2944cc4ab024bc5George Mount } 444500be62dea3895a98336122a2944cc4ab024bc5George Mount 45990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 46990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Wraps a transition in a TransitionSet and returns the set. If transition is null, null is 47990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * returned. 48990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 49990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static Object wrapTransitionInSet(Object transition) { 50c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount if (transition == null) { 51c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount return null; 52c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 53c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount TransitionSet transitionSet = new TransitionSet(); 54990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transitionSet.addTransition((Transition) transition); 55c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount return transitionSet; 56c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 57c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount 58c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount /** 59c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount * Finds all children of the shared elements and sets the wrapping TransitionSet 60c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount * targets to point to those. It also limits transitions that have no targets to the 61c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount * specific shared elements. This allows developers to target child views of the 62c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount * shared elements specifically, but this doesn't happen by default. 63c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount */ 64c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount public static void setSharedElementTargets(Object transitionObj, 65990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount View nonExistentView, ArrayList<View> sharedViews) { 66c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount TransitionSet transition = (TransitionSet) transitionObj; 67c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount final List<View> views = transition.getTargets(); 68c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount views.clear(); 69990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int count = sharedViews.size(); 70c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount for (int i = 0; i < count; i++) { 71990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View view = sharedViews.get(i); 72c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount bfsAddViewChildren(views, view); 73c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 74990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount views.add(nonExistentView); 75990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount sharedViews.add(nonExistentView); 76990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount addTargets(transition, sharedViews); 77c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 789f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount 79c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount /** 80c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount * Uses a breadth-first scheme to add startView and all of its children to views. 81c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount * It won't add a child if it is already in views. 82c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount */ 83c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount private static void bfsAddViewChildren(final List<View> views, final View startView) { 84c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount final int startIndex = views.size(); 85c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount if (containedBeforeIndex(views, startView, startIndex)) { 86c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount return; // This child is already in the list, so all its children are also. 87c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 88c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount views.add(startView); 89c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount for (int index = startIndex; index < views.size(); index++) { 90c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount final View view = views.get(index); 91c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount if (view instanceof ViewGroup) { 92c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount ViewGroup viewGroup = (ViewGroup) view; 93c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount final int childCount = viewGroup.getChildCount(); 94c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount for (int childIndex = 0; childIndex < childCount; childIndex++) { 95c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount final View child = viewGroup.getChildAt(childIndex); 96c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount if (!containedBeforeIndex(views, child, startIndex)) { 97c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount views.add(child); 98c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 99c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 100c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 101c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 102c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 103c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount 104c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount /** 105c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount * Does a linear search through views for view, limited to maxIndex. 106c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount */ 107c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount private static boolean containedBeforeIndex(final List<View> views, final View view, 108c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount final int maxIndex) { 109c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount for (int i = 0; i < maxIndex; i++) { 110c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount if (views.get(i) == view) { 111c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount return true; 112c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 113c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 114c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount return false; 115c33885b865c99ce9ae96214f0e9d7bd1ca12cb93George Mount } 1169f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount 117990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 118990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Sets a transition epicenter to the rectangle of a given View. 119990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 120990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void setEpicenter(Object transitionObj, View view) { 121990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (view != null) { 122990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Transition transition = (Transition) transitionObj; 123990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Rect epicenter = new Rect(); 124990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount getBoundsOnScreen(view, epicenter); 1250f5ae57910484f1d873fdad90966b6244a633bd4George Mount 126990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transition.setEpicenterCallback(new Transition.EpicenterCallback() { 1270f5ae57910484f1d873fdad90966b6244a633bd4George Mount @Override 1280f5ae57910484f1d873fdad90966b6244a633bd4George Mount public Rect onGetEpicenter(Transition transition) { 129990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return epicenter; 1304500be62dea3895a98336122a2944cc4ab024bc5George Mount } 1310f5ae57910484f1d873fdad90966b6244a633bd4George Mount }); 1320f5ae57910484f1d873fdad90966b6244a633bd4George Mount } 1334500be62dea3895a98336122a2944cc4ab024bc5George Mount } 1344500be62dea3895a98336122a2944cc4ab024bc5George Mount 135990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 136990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Replacement for view.getBoundsOnScreen because that is not public. This returns a rect 137990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * containing the bounds relative to the screen that the view is in. 138990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 139990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void getBoundsOnScreen(View view, Rect epicenter) { 1404500be62dea3895a98336122a2944cc4ab024bc5George Mount int[] loc = new int[2]; 1414500be62dea3895a98336122a2944cc4ab024bc5George Mount view.getLocationOnScreen(loc); 1424500be62dea3895a98336122a2944cc4ab024bc5George Mount epicenter.set(loc[0], loc[1], loc[0] + view.getWidth(), loc[1] + view.getHeight()); 1434500be62dea3895a98336122a2944cc4ab024bc5George Mount } 1444500be62dea3895a98336122a2944cc4ab024bc5George Mount 145990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 146990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This method adds views as targets to the transition, but only if the transition 147990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * doesn't already have a target. It is best for views to contain one View object 148990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * that does not exist in the view hierarchy (state.nonExistentView) so that 149990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * when they are removed later, a list match will suffice to remove the targets. 150990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Otherwise, if you happened to have targeted the exact views for the transition, 151990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * the replaceTargets call will remove them unexpectedly. 152990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 153990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void addTargets(Object transitionObj, ArrayList<View> views) { 154990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Transition transition = (Transition) transitionObj; 155990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (transition == null) { 156990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return; 157990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 158990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (transition instanceof TransitionSet) { 159990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount TransitionSet set = (TransitionSet) transition; 160990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int numTransitions = set.getTransitionCount(); 161990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numTransitions; i++) { 162990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Transition child = set.getTransitionAt(i); 163990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount addTargets(child, views); 164990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 165990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else if (!hasSimpleTarget(transition)) { 166990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount List<View> targets = transition.getTargets(); 167990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (isNullOrEmpty(targets)) { 168990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // We can just add the target views 169990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount int numViews = views.size(); 170990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numViews; i++) { 171990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transition.addTarget(views.get(i)); 172990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 173990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 174990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 175990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 176990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 177990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 178990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Returns true if there are any targets based on ID, transition or type. 179990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 180990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static boolean hasSimpleTarget(Transition transition) { 181990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return !isNullOrEmpty(transition.getTargetIds()) 182990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount || !isNullOrEmpty(transition.getTargetNames()) 183990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount || !isNullOrEmpty(transition.getTargetTypes()); 184990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 185990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 186990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 187990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Simple utility to detect if a list is null or has no elements. 188990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 189990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static boolean isNullOrEmpty(List list) { 190990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return list == null || list.isEmpty(); 191990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 192990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 193990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 194990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Creates a TransitionSet that plays all passed transitions together. Any null 195990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transitions passed will not be added to the set. If all are null, then an empty 196990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * TransitionSet will be returned. 197990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 198990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static Object mergeTransitionsTogether(Object transition1, Object transition2, 199990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Object transition3) { 200990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount TransitionSet transitionSet = new TransitionSet(); 201990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (transition1 != null) { 202990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transitionSet.addTransition((Transition) transition1); 203990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 204990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (transition2 != null) { 205990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transitionSet.addTransition((Transition) transition2); 206990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 207990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (transition3 != null) { 208990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transitionSet.addTransition((Transition) transition3); 209990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 210990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return transitionSet; 211990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 212990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 213990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 214667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount * After the transition completes, the fragment's view is set to GONE and the exiting 215667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount * views are set to VISIBLE. 216667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount */ 217667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount public static void scheduleHideFragmentView(Object exitTransitionObj, final View fragmentView, 218667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount final ArrayList<View> exitingViews) { 219667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount Transition exitTransition = (Transition) exitTransitionObj; 220667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount exitTransition.addListener(new Transition.TransitionListener() { 221667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount @Override 222667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount public void onTransitionStart(Transition transition) { 223667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount } 224667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount 225667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount @Override 226667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount public void onTransitionEnd(Transition transition) { 227667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount transition.removeListener(this); 228667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount fragmentView.setVisibility(View.GONE); 229667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount final int numViews = exitingViews.size(); 230667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount for (int i = 0; i < numViews; i++) { 231667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount exitingViews.get(i).setVisibility(View.VISIBLE); 232667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount } 233667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount } 234667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount 235667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount @Override 236667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount public void onTransitionCancel(Transition transition) { 237667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount } 238667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount 239667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount @Override 240667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount public void onTransitionPause(Transition transition) { 241667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount } 242667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount 243667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount @Override 244667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount public void onTransitionResume(Transition transition) { 245667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount } 246667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount }); 247667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount } 248667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount 249667ec4150c78bf295b3db1fa4d546def9ade9d20George Mount /** 250990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Combines enter, exit, and shared element transition so that they play in the proper 251990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * sequence. First the exit transition plays along with the shared element transition. 252990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * When the exit transition completes, the enter transition starts. The shared element 253990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * transition can continue running while the enter transition plays. 254990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * 255990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @return A TransitionSet with all of enter, exit, and shared element transitions in 256990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * it (modulo null values), ordered such that they play in the proper sequence. 257990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 258990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static Object mergeTransitionsInSequence(Object exitTransitionObj, 259990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Object enterTransitionObj, Object sharedElementTransitionObj) { 260990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // First do exit, then enter, but allow shared element transition to happen 261990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // during both. 262990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Transition staggered = null; 263990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Transition exitTransition = (Transition) exitTransitionObj; 264990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Transition enterTransition = (Transition) enterTransitionObj; 265990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Transition sharedElementTransition = (Transition) sharedElementTransitionObj; 266990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (exitTransition != null && enterTransition != null) { 267990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount staggered = new TransitionSet() 268990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addTransition(exitTransition) 269990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .addTransition(enterTransition) 270990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount .setOrdering(TransitionSet.ORDERING_SEQUENTIAL); 271990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else if (exitTransition != null) { 272990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount staggered = exitTransition; 273990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else if (enterTransition != null) { 274990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount staggered = enterTransition; 275990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 276990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (sharedElementTransition != null) { 277990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount TransitionSet together = new TransitionSet(); 278990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (staggered != null) { 279990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount together.addTransition(staggered); 280990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 281990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount together.addTransition(sharedElementTransition); 282990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return together; 283990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } else { 284990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return staggered; 285990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 286990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 287990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 288990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 289990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Calls {@link TransitionManager#beginDelayedTransition(ViewGroup, Transition)}. 290990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 291990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void beginDelayedTransition(ViewGroup sceneRoot, Object transition) { 292990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount TransitionManager.beginDelayedTransition(sceneRoot, (Transition) transition); 293990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 294990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 295990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 296990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Prepares for setting the shared element names by gathering the names of the incoming 297fda5be2466024a656152015c45a7681361d399bbGeorge Mount * shared elements and clearing them. {@link #setNameOverridesReordered(View, ArrayList, 298990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * ArrayList, ArrayList, Map)} must be called after this to complete setting the shared element 299990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * name overrides. This must be called before 300990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #beginDelayedTransition(ViewGroup, Object)}. 301990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 302fda5be2466024a656152015c45a7681361d399bbGeorge Mount public static ArrayList<String> prepareSetNameOverridesReordered( 303990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ArrayList<View> sharedElementsIn) { 304990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ArrayList<String> names = new ArrayList<>(); 305990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numSharedElements = sharedElementsIn.size(); 306990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numSharedElements; i++) { 307990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View view = sharedElementsIn.get(i); 308990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount names.add(view.getTransitionName()); 309990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount view.setTransitionName(null); 310990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 311990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return names; 312990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 313990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 314990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 315990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Changes the shared element names for the incoming shared eleemnts to match those of the 316990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * outgoing shared elements. This also temporarily clears the shared element names of the 317990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * outgoing shared elements. Must be called after 318990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link #beginDelayedTransition(ViewGroup, Object)}. 319990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 320fda5be2466024a656152015c45a7681361d399bbGeorge Mount public static void setNameOverridesReordered(final View sceneRoot, 321990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ArrayList<View> sharedElementsOut, final ArrayList<View> sharedElementsIn, 322990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ArrayList<String> inNames, final Map<String, String> nameOverrides) { 323990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int numSharedElements = sharedElementsIn.size(); 324990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ArrayList<String> outNames = new ArrayList<>(); 325990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 326990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < numSharedElements; i++) { 327990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final View view = sharedElementsOut.get(i); 328990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final String name = view.getTransitionName(); 329990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount outNames.add(name); 330990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (name == null) { 331990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount continue; 332990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 333990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount view.setTransitionName(null); 334990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final String inName = nameOverrides.get(name); 335990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int j = 0; j < numSharedElements; j++) { 336990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (inName.equals(inNames.get(j))) { 337990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount sharedElementsIn.get(j).setTransitionName(name); 338990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount break; 339990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 340990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 341990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 342990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 3437d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount OneShotPreDrawListener.add(sceneRoot, new Runnable() { 3447d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount @Override 3457d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount public void run() { 3467d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount for (int i = 0; i < numSharedElements; i++) { 3477d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount sharedElementsIn.get(i).setTransitionName(inNames.get(i)); 3487d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount sharedElementsOut.get(i).setTransitionName(outNames.get(i)); 3497d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount } 3507d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount } 3517d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount }); 352990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 353990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 354990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 355990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Gets the Views in the hierarchy affected by entering and exiting Activity Scene transitions. 356990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param transitioningViews This View will be added to transitioningViews if it is VISIBLE and 357990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * a normal View or a ViewGroup with 358990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * {@link android.view.ViewGroup#isTransitionGroup()} true. 359990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * @param view The base of the view hierarchy to look in. 360990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 361990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void captureTransitioningViews(ArrayList<View> transitioningViews, View view) { 3624500be62dea3895a98336122a2944cc4ab024bc5George Mount if (view.getVisibility() == View.VISIBLE) { 3634500be62dea3895a98336122a2944cc4ab024bc5George Mount if (view instanceof ViewGroup) { 3644500be62dea3895a98336122a2944cc4ab024bc5George Mount ViewGroup viewGroup = (ViewGroup) view; 3654500be62dea3895a98336122a2944cc4ab024bc5George Mount if (viewGroup.isTransitionGroup()) { 3664500be62dea3895a98336122a2944cc4ab024bc5George Mount transitioningViews.add(viewGroup); 3674500be62dea3895a98336122a2944cc4ab024bc5George Mount } else { 3684500be62dea3895a98336122a2944cc4ab024bc5George Mount int count = viewGroup.getChildCount(); 3694500be62dea3895a98336122a2944cc4ab024bc5George Mount for (int i = 0; i < count; i++) { 3704500be62dea3895a98336122a2944cc4ab024bc5George Mount View child = viewGroup.getChildAt(i); 3714500be62dea3895a98336122a2944cc4ab024bc5George Mount captureTransitioningViews(transitioningViews, child); 3724500be62dea3895a98336122a2944cc4ab024bc5George Mount } 3734500be62dea3895a98336122a2944cc4ab024bc5George Mount } 3744500be62dea3895a98336122a2944cc4ab024bc5George Mount } else { 3754500be62dea3895a98336122a2944cc4ab024bc5George Mount transitioningViews.add(view); 3764500be62dea3895a98336122a2944cc4ab024bc5George Mount } 3774500be62dea3895a98336122a2944cc4ab024bc5George Mount } 3784500be62dea3895a98336122a2944cc4ab024bc5George Mount } 3794500be62dea3895a98336122a2944cc4ab024bc5George Mount 380990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 381990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Finds all views that have transition names in the hierarchy under the given view and 382990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * stores them in {@code namedViews} map with the name as the key. 383990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 3849f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount public static void findNamedViews(Map<String, View> namedViews, View view) { 3854500be62dea3895a98336122a2944cc4ab024bc5George Mount if (view.getVisibility() == View.VISIBLE) { 3864500be62dea3895a98336122a2944cc4ab024bc5George Mount String transitionName = view.getTransitionName(); 3874500be62dea3895a98336122a2944cc4ab024bc5George Mount if (transitionName != null) { 3884500be62dea3895a98336122a2944cc4ab024bc5George Mount namedViews.put(transitionName, view); 3894500be62dea3895a98336122a2944cc4ab024bc5George Mount } 3904500be62dea3895a98336122a2944cc4ab024bc5George Mount if (view instanceof ViewGroup) { 3914500be62dea3895a98336122a2944cc4ab024bc5George Mount ViewGroup viewGroup = (ViewGroup) view; 3924500be62dea3895a98336122a2944cc4ab024bc5George Mount int count = viewGroup.getChildCount(); 3934500be62dea3895a98336122a2944cc4ab024bc5George Mount for (int i = 0; i < count; i++) { 3944500be62dea3895a98336122a2944cc4ab024bc5George Mount View child = viewGroup.getChildAt(i); 3954500be62dea3895a98336122a2944cc4ab024bc5George Mount findNamedViews(namedViews, child); 3964500be62dea3895a98336122a2944cc4ab024bc5George Mount } 3974500be62dea3895a98336122a2944cc4ab024bc5George Mount } 3984500be62dea3895a98336122a2944cc4ab024bc5George Mount } 3994500be62dea3895a98336122a2944cc4ab024bc5George Mount } 4004500be62dea3895a98336122a2944cc4ab024bc5George Mount 401fda5be2466024a656152015c45a7681361d399bbGeorge Mount public static void setNameOverridesOrdered(final View sceneRoot, 402990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ArrayList<View> sharedElementsIn, final Map<String, String> nameOverrides) { 4037d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount OneShotPreDrawListener.add(sceneRoot, new Runnable() { 4047d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount @Override 4057d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount public void run() { 4067d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount final int numSharedElements = sharedElementsIn.size(); 4077d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount for (int i = 0; i < numSharedElements; i++) { 4087d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount View view = sharedElementsIn.get(i); 4097d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount String name = view.getTransitionName(); 4107d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount if (name != null) { 4117d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount String inName = findKeyForValue(nameOverrides, name); 4127d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount view.setTransitionName(inName); 4130f5ae57910484f1d873fdad90966b6244a633bd4George Mount } 4147d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount } 4157d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount } 4167d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount }); 4170f5ae57910484f1d873fdad90966b6244a633bd4George Mount } 4184500be62dea3895a98336122a2944cc4ab024bc5George Mount 419c766ad5a6e0c115f08b933ede22375c7070a3391George Mount /** 420990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Utility to find the String key in {@code map} that maps to {@code value}. 421c766ad5a6e0c115f08b933ede22375c7070a3391George Mount */ 422990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount private static String findKeyForValue(Map<String, String> map, String value) { 423990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (Map.Entry<String, String> entry : map.entrySet()) { 424990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (value.equals(entry.getValue())) { 425990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return entry.getKey(); 426c766ad5a6e0c115f08b933ede22375c7070a3391George Mount } 427990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 428990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return null; 429990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 430990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 431990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 432990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * After the transition has started, remove all targets that we added to the transitions 433990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * so that the transitions are left in a clean state. 434990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 435990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void scheduleRemoveTargets(final Object overallTransitionObj, 436990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Object enterTransition, final ArrayList<View> enteringViews, 437990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Object exitTransition, final ArrayList<View> exitingViews, 438990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Object sharedElementTransition, final ArrayList<View> sharedElementsIn) { 439990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final Transition overallTransition = (Transition) overallTransitionObj; 440990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount overallTransition.addListener(new Transition.TransitionListener() { 441990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 442990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void onTransitionStart(Transition transition) { 443990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (enterTransition != null) { 444990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount replaceTargets(enterTransition, enteringViews, null); 445990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 446990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (exitTransition != null) { 447990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount replaceTargets(exitTransition, exitingViews, null); 448990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 449990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (sharedElementTransition != null) { 450990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount replaceTargets(sharedElementTransition, sharedElementsIn, null); 451c766ad5a6e0c115f08b933ede22375c7070a3391George Mount } 452c766ad5a6e0c115f08b933ede22375c7070a3391George Mount } 453990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 454990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 455990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void onTransitionEnd(Transition transition) { 456990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 457990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 458990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 459990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void onTransitionCancel(Transition transition) { 460990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 461990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 462990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 463990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void onTransitionPause(Transition transition) { 464990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 465990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 466990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 467990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public void onTransitionResume(Transition transition) { 468990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 469990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount }); 470990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 471990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 472990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 473990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Swap the targets for the shared element transition from those Views in sharedElementsOut 474990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * to those in sharedElementsIn 475990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 476990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void swapSharedElementTargets(Object sharedElementTransitionObj, 477990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<View> sharedElementsOut, ArrayList<View> sharedElementsIn) { 478990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount TransitionSet sharedElementTransition = (TransitionSet) sharedElementTransitionObj; 479990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (sharedElementTransition != null) { 480990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount sharedElementTransition.getTargets().clear(); 481990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount sharedElementTransition.getTargets().addAll(sharedElementsIn); 482990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount replaceTargets(sharedElementTransition, sharedElementsOut, sharedElementsIn); 4834500be62dea3895a98336122a2944cc4ab024bc5George Mount } 4840f5ae57910484f1d873fdad90966b6244a633bd4George Mount } 4859f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount 486990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount 487c766ad5a6e0c115f08b933ede22375c7070a3391George Mount /** 488990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * This method removes the views from transitions that target ONLY those views and 489990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * replaces them with the new targets list. 490990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * The views list should match those added in addTargets and should contain 491990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * one view that is not in the view hierarchy (state.nonExistentView). 492c766ad5a6e0c115f08b933ede22375c7070a3391George Mount */ 493990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void replaceTargets(Object transitionObj, ArrayList<View> oldTargets, 494990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount ArrayList<View> newTargets) { 495990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Transition transition = (Transition) transitionObj; 496c766ad5a6e0c115f08b933ede22375c7070a3391George Mount if (transition instanceof TransitionSet) { 497c766ad5a6e0c115f08b933ede22375c7070a3391George Mount TransitionSet set = (TransitionSet) transition; 498c766ad5a6e0c115f08b933ede22375c7070a3391George Mount int numTransitions = set.getTransitionCount(); 499c766ad5a6e0c115f08b933ede22375c7070a3391George Mount for (int i = 0; i < numTransitions; i++) { 500c766ad5a6e0c115f08b933ede22375c7070a3391George Mount Transition child = set.getTransitionAt(i); 501990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount replaceTargets(child, oldTargets, newTargets); 502c766ad5a6e0c115f08b933ede22375c7070a3391George Mount } 503c766ad5a6e0c115f08b933ede22375c7070a3391George Mount } else if (!hasSimpleTarget(transition)) { 504c766ad5a6e0c115f08b933ede22375c7070a3391George Mount List<View> targets = transition.getTargets(); 505990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (targets != null && targets.size() == oldTargets.size() 506990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount && targets.containsAll(oldTargets)) { 507990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount // We have an exact match. We must have added these earlier in addTargets 508990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final int targetCount = newTargets == null ? 0 : newTargets.size(); 509990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = 0; i < targetCount; i++) { 510990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transition.addTarget(newTargets.get(i)); 511990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 512990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount for (int i = oldTargets.size() - 1; i >= 0; i--) { 513990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transition.removeTarget(oldTargets.get(i)); 514c766ad5a6e0c115f08b933ede22375c7070a3391George Mount } 515c766ad5a6e0c115f08b933ede22375c7070a3391George Mount } 5169f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount } 5179f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount } 5189f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount 519990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 520990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Adds a View target to a transition. If transitionObj is null, nothing is done. 521990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 522990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void addTarget(Object transitionObj, View view) { 523990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (transitionObj != null) { 524990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Transition transition = (Transition) transitionObj; 525990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transition.addTarget(view); 526990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 527c766ad5a6e0c115f08b933ede22375c7070a3391George Mount } 528c766ad5a6e0c115f08b933ede22375c7070a3391George Mount 529990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 530990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Remove a View target to a transition. If transitionObj is null, nothing is done. 531990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 532990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void removeTarget(Object transitionObj, View view) { 533990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (transitionObj != null) { 534990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Transition transition = (Transition) transitionObj; 535990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transition.removeTarget(view); 536990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 537c766ad5a6e0c115f08b933ede22375c7070a3391George Mount } 538c766ad5a6e0c115f08b933ede22375c7070a3391George Mount 539990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount /** 540990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * Sets the epicenter of a transition to a rect object. The object can be modified until 541990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount * the transition runs. 542990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount */ 543990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void setEpicenter(Object transitionObj, final Rect epicenter) { 544990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (transitionObj != null) { 545990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount Transition transition = (Transition) transitionObj; 546990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount transition.setEpicenterCallback(new Transition.EpicenterCallback() { 547990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount @Override 548990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public Rect onGetEpicenter(Transition transition) { 549990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount if (epicenter == null || epicenter.isEmpty()) { 550990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return null; 551990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 552990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount return epicenter; 553990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 554990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount }); 555990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount } 5569f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount } 5579f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount 558990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount public static void scheduleNameReset(final ViewGroup sceneRoot, 559990e6fc0326f5948736650c0cb71b6002d443c9cGeorge Mount final ArrayList<View> sharedElementsIn, final Map<String, String> nameOverrides) { 5607d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount OneShotPreDrawListener.add(sceneRoot, new Runnable() { 5617d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount @Override 5627d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount public void run() { 5637d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount final int numSharedElements = sharedElementsIn.size(); 5647d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount for (int i = 0; i < numSharedElements; i++) { 5657d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount final View view = sharedElementsIn.get(i); 5667d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount final String name = view.getTransitionName(); 5677d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount final String inName = nameOverrides.get(name); 5687d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount view.setTransitionName(inName); 5697d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount } 5707d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount } 5717d542b74cbd4d5c68193e230fa4af96cecfc7dbbGeorge Mount }); 5729f4a046cbeb22a24d322a644323b41022ad9d15aGeorge Mount } 5734500be62dea3895a98336122a2944cc4ab024bc5George Mount} 574