am 19c1cbda: Merge "Only modify add Transition targets when they aren\'t targeted." into lmp-mr1-dev

* commit '19c1cbda5a00b92e4e8c31b820b652c75a6c0a06':
  Only modify add Transition targets when they aren't targeted.
This commit is contained in:
George Mount
2014-11-10 23:53:15 +00:00
committed by Android Git Automerger

View File

@@ -38,6 +38,7 @@ import android.view.ViewTreeObserver;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
final class BackStackState implements Parcelable { final class BackStackState implements Parcelable {
final int[] mOps; final int[] mOps;
@@ -1055,7 +1056,7 @@ final class BackStackRecord extends FragmentTransaction implements
} }
private static ArrayList<View> captureExitingViews(Transition exitTransition, 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; ArrayList<View> viewList = null;
if (exitTransition != null) { if (exitTransition != null) {
viewList = new ArrayList<View>(); viewList = new ArrayList<View>();
@@ -1064,8 +1065,11 @@ final class BackStackRecord extends FragmentTransaction implements
if (namedViews != null) { if (namedViews != null) {
viewList.removeAll(namedViews.values()); viewList.removeAll(namedViews.values());
} }
if (!viewList.isEmpty()) {
viewList.add(nonExistentView);
addTargets(exitTransition, viewList); addTargets(exitTransition, viewList);
} }
}
return viewList; return viewList;
} }
@@ -1132,11 +1136,8 @@ final class BackStackRecord extends FragmentTransaction implements
namedViews = mapSharedElementsIn(state, isBack, inFragment); namedViews = mapSharedElementsIn(state, isBack, inFragment);
removeTargets(sharedElementTransition, sharedElementTargets); removeTargets(sharedElementTransition, sharedElementTargets);
sharedElementTargets.clear(); sharedElementTargets.clear();
if (namedViews.isEmpty()) {
sharedElementTargets.add(state.nonExistentView); sharedElementTargets.add(state.nonExistentView);
} else {
sharedElementTargets.addAll(namedViews.values()); sharedElementTargets.addAll(namedViews.values());
}
addTargets(sharedElementTransition, sharedElementTargets); addTargets(sharedElementTransition, sharedElementTargets);
@@ -1153,6 +1154,9 @@ final class BackStackRecord extends FragmentTransaction implements
if (namedViews != null) { if (namedViews != null) {
enteringViews.removeAll(namedViews.values()); 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); addTargets(enterTransition, enteringViews);
} }
setSharedElementEpicenter(enterTransition, state); setSharedElementEpicenter(enterTransition, state);
@@ -1293,11 +1297,8 @@ final class BackStackRecord extends FragmentTransaction implements
ArrayList<View> sharedElementTargets = new ArrayList<View>(); ArrayList<View> sharedElementTargets = new ArrayList<View>();
if (sharedElementTransition != null) { if (sharedElementTransition != null) {
namedViews = remapSharedElements(state, outFragment, isBack); namedViews = remapSharedElements(state, outFragment, isBack);
if (namedViews.isEmpty()) {
sharedElementTargets.add(state.nonExistentView); sharedElementTargets.add(state.nonExistentView);
} else {
sharedElementTargets.addAll(namedViews.values()); sharedElementTargets.addAll(namedViews.values());
}
addTargets(sharedElementTransition, sharedElementTargets); addTargets(sharedElementTransition, sharedElementTargets);
// Notify the start of the transition. // Notify the start of the transition.
@@ -1310,7 +1311,7 @@ final class BackStackRecord extends FragmentTransaction implements
} }
ArrayList<View> exitingViews = captureExitingViews(exitTransition, outFragment, ArrayList<View> exitingViews = captureExitingViews(exitTransition, outFragment,
namedViews); namedViews, state.nonExistentView);
if (exitingViews == null || exitingViews.isEmpty()) { if (exitingViews == null || exitingViews.isEmpty()) {
exitTransition = null; exitTransition = null;
} }
@@ -1388,19 +1389,68 @@ final class BackStackRecord extends FragmentTransaction implements
} }
} }
private static void removeTargets(Transition transition, ArrayList<View> views) { /**
int numViews = views.size(); * This method removes the views from transitions that target ONLY those views.
for (int i = 0; i < numViews; i++) { * 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)); transition.removeTarget(views.get(i));
} }
} }
}
}
private static void addTargets(Transition transition, ArrayList<View> views) { /**
* 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(); int numViews = views.size();
for (int i = 0; i < numViews; i++) { for (int i = 0; i < numViews; i++) {
transition.addTarget(views.get(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. * Remaps a name-to-View map, substituting different names for keys.