Merge "Only modify add Transition targets when they aren't targeted." into lmp-mr1-dev
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user