diff options
author | George Mount <mount@google.com> | 2014-11-10 23:48:32 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-11-10 23:48:34 +0000 |
commit | 19c1cbda5a00b92e4e8c31b820b652c75a6c0a06 (patch) | |
tree | 7f4ac08c266e33785cce9e57dbaf774edfa1bd29 | |
parent | 465e0532491442a2814a37c939a650b3c4119b31 (diff) | |
parent | 7ce5d75dc920823d83e2e34fefc3875dc8868411 (diff) | |
download | frameworks_base-19c1cbda5a00b92e4e8c31b820b652c75a6c0a06.zip frameworks_base-19c1cbda5a00b92e4e8c31b820b652c75a6c0a06.tar.gz frameworks_base-19c1cbda5a00b92e4e8c31b820b652c75a6c0a06.tar.bz2 |
Merge "Only modify add Transition targets when they aren't targeted." into lmp-mr1-dev
-rw-r--r-- | core/java/android/app/BackStackRecord.java | 92 |
1 files changed, 71 insertions, 21 deletions
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java index 0092ee7..2784d44 100644 --- a/core/java/android/app/BackStackRecord.java +++ b/core/java/android/app/BackStackRecord.java @@ -38,6 +38,7 @@ import android.view.ViewTreeObserver; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; final class BackStackState implements Parcelable { final int[] mOps; @@ -1055,7 +1056,7 @@ final class BackStackRecord extends FragmentTransaction implements } private static ArrayList<View> captureExitingViews(Transition exitTransition, - Fragment outFragment, ArrayMap<String, View> namedViews) { + Fragment outFragment, ArrayMap<String, View> namedViews, View nonExistentView) { ArrayList<View> viewList = null; if (exitTransition != null) { viewList = new ArrayList<View>(); @@ -1064,7 +1065,10 @@ final class BackStackRecord extends FragmentTransaction implements if (namedViews != null) { viewList.removeAll(namedViews.values()); } - addTargets(exitTransition, viewList); + if (!viewList.isEmpty()) { + viewList.add(nonExistentView); + addTargets(exitTransition, viewList); + } } return viewList; } @@ -1132,11 +1136,8 @@ final class BackStackRecord extends FragmentTransaction implements namedViews = mapSharedElementsIn(state, isBack, inFragment); removeTargets(sharedElementTransition, sharedElementTargets); sharedElementTargets.clear(); - if (namedViews.isEmpty()) { - sharedElementTargets.add(state.nonExistentView); - } else { - sharedElementTargets.addAll(namedViews.values()); - } + sharedElementTargets.add(state.nonExistentView); + sharedElementTargets.addAll(namedViews.values()); addTargets(sharedElementTransition, sharedElementTargets); @@ -1153,6 +1154,9 @@ final class BackStackRecord extends FragmentTransaction implements if (namedViews != null) { enteringViews.removeAll(namedViews.values()); } + enteringViews.add(state.nonExistentView); + // We added this earlier to prevent any views being targeted. + enterTransition.removeTarget(state.nonExistentView); addTargets(enterTransition, enteringViews); } setSharedElementEpicenter(enterTransition, state); @@ -1293,11 +1297,8 @@ final class BackStackRecord extends FragmentTransaction implements ArrayList<View> sharedElementTargets = new ArrayList<View>(); if (sharedElementTransition != null) { namedViews = remapSharedElements(state, outFragment, isBack); - if (namedViews.isEmpty()) { - sharedElementTargets.add(state.nonExistentView); - } else { - sharedElementTargets.addAll(namedViews.values()); - } + sharedElementTargets.add(state.nonExistentView); + sharedElementTargets.addAll(namedViews.values()); addTargets(sharedElementTransition, sharedElementTargets); // Notify the start of the transition. @@ -1310,7 +1311,7 @@ final class BackStackRecord extends FragmentTransaction implements } ArrayList<View> exitingViews = captureExitingViews(exitTransition, outFragment, - namedViews); + namedViews, state.nonExistentView); if (exitingViews == null || exitingViews.isEmpty()) { exitTransition = null; } @@ -1388,20 +1389,69 @@ final class BackStackRecord extends FragmentTransaction implements } } - private static void removeTargets(Transition transition, ArrayList<View> views) { - int numViews = views.size(); - for (int i = 0; i < numViews; i++) { - transition.removeTarget(views.get(i)); + /** + * This method removes the views from transitions that target ONLY those views. + * The views list should match those added in addTargets and should contain + * one view that is not in the view hierarchy (state.nonExistentView). + */ + public static void removeTargets(Transition transition, ArrayList<View> views) { + if (transition instanceof TransitionSet) { + TransitionSet set = (TransitionSet) transition; + int numTransitions = set.getTransitionCount(); + for (int i = 0; i < numTransitions; i++) { + Transition child = set.getTransitionAt(i); + removeTargets(child, views); + } + } else if (!hasSimpleTarget(transition)) { + List<View> targets = transition.getTargets(); + if (targets != null && targets.size() == views.size() && + targets.containsAll(views)) { + // We have an exact match. We must have added these earlier in addTargets + for (int i = views.size() - 1; i >= 0; i--) { + transition.removeTarget(views.get(i)); + } + } } } - private static void addTargets(Transition transition, ArrayList<View> views) { - int numViews = views.size(); - for (int i = 0; i < numViews; i++) { - transition.addTarget(views.get(i)); + /** + * This method adds views as targets to the transition, but only if the transition + * doesn't already have a target. It is best for views to contain one View object + * that does not exist in the view hierarchy (state.nonExistentView) so that + * when they are removed later, a list match will suffice to remove the targets. + * Otherwise, if you happened to have targeted the exact views for the transition, + * the removeTargets call will remove them unexpectedly. + */ + public static void addTargets(Transition transition, ArrayList<View> views) { + if (transition instanceof TransitionSet) { + TransitionSet set = (TransitionSet) transition; + int numTransitions = set.getTransitionCount(); + for (int i = 0; i < numTransitions; i++) { + Transition child = set.getTransitionAt(i); + addTargets(child, views); + } + } else if (!hasSimpleTarget(transition)) { + List<View> targets = transition.getTargets(); + if (isNullOrEmpty(targets)) { + // We can just add the target views + int numViews = views.size(); + for (int i = 0; i < numViews; i++) { + transition.addTarget(views.get(i)); + } + } } } + private static boolean hasSimpleTarget(Transition transition) { + return !isNullOrEmpty(transition.getTargetIds()) || + !isNullOrEmpty(transition.getTargetNames()) || + !isNullOrEmpty(transition.getTargetTypes()); + } + + private static boolean isNullOrEmpty(List list) { + return list == null || list.isEmpty(); + } + /** * Remaps a name-to-View map, substituting different names for keys. * |