Fix NPE when a shared element doesn't have a matching transitionName.
Bug 33053923 Also added an early error check when the same shared element is used for multiple shared elements in the source or target fragment. Test: If5dfbac66cfd9e60660439ce5c519547de3ef1d0 Change-Id: Iac3ab8c1b8ea0208a0c76e043654184dd634948d
This commit is contained in:
@@ -534,6 +534,12 @@ final class BackStackRecord extends FragmentTransaction implements
|
||||
if (mSharedElementSourceNames == null) {
|
||||
mSharedElementSourceNames = new ArrayList<String>();
|
||||
mSharedElementTargetNames = new ArrayList<String>();
|
||||
} else if (mSharedElementTargetNames.contains(name)) {
|
||||
throw new IllegalArgumentException("A shared element with the target name '"
|
||||
+ name + "' has already been added to the transaction.");
|
||||
} else if (mSharedElementSourceNames.contains(transitionName)) {
|
||||
throw new IllegalArgumentException("A shared element with the source name '"
|
||||
+ transitionName + " has already been added to the transaction.");
|
||||
}
|
||||
mSharedElementSourceNames.add(transitionName);
|
||||
mSharedElementTargetNames.add(name);
|
||||
|
||||
@@ -367,9 +367,11 @@ class FragmentTransition {
|
||||
}
|
||||
|
||||
if (exitingViews != null) {
|
||||
ArrayList<View> tempExiting = new ArrayList<>();
|
||||
tempExiting.add(nonExistentView);
|
||||
replaceTargets(exitTransition, exitingViews, tempExiting);
|
||||
if (exitTransition != null) {
|
||||
ArrayList<View> tempExiting = new ArrayList<>();
|
||||
tempExiting.add(nonExistentView);
|
||||
replaceTargets(exitTransition, exitingViews, tempExiting);
|
||||
}
|
||||
exitingViews.clear();
|
||||
exitingViews.add(nonExistentView);
|
||||
}
|
||||
@@ -490,9 +492,17 @@ class FragmentTransition {
|
||||
|
||||
if (nameOverrides.isEmpty()) {
|
||||
sharedElementTransition = null;
|
||||
if (outSharedElements != null) {
|
||||
outSharedElements.clear();
|
||||
}
|
||||
if (inSharedElements != null) {
|
||||
inSharedElements.clear();
|
||||
}
|
||||
} else {
|
||||
sharedElementsOut.addAll(outSharedElements.values());
|
||||
sharedElementsIn.addAll(inSharedElements.values());
|
||||
addSharedElementsWithMatchingNames(sharedElementsOut, outSharedElements,
|
||||
nameOverrides.keySet());
|
||||
addSharedElementsWithMatchingNames(sharedElementsIn, inSharedElements,
|
||||
nameOverrides.values());
|
||||
}
|
||||
|
||||
if (enterTransition == null && exitTransition == null && sharedElementTransition == null) {
|
||||
@@ -537,6 +547,25 @@ class FragmentTransition {
|
||||
return sharedElementTransition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Views from sharedElements into views that have the transitionName in the
|
||||
* nameOverridesSet.
|
||||
*
|
||||
* @param views Views list to add shared elements to
|
||||
* @param sharedElements List of shared elements
|
||||
* @param nameOverridesSet The transition names for all views to be copied from
|
||||
* sharedElements to views.
|
||||
*/
|
||||
private static void addSharedElementsWithMatchingNames(ArrayList<View> views,
|
||||
ArrayMap<String, View> sharedElements, Collection<String> nameOverridesSet) {
|
||||
for (int i = sharedElements.size() - 1; i >= 0; i--) {
|
||||
View view = sharedElements.valueAt(i);
|
||||
if (view != null && nameOverridesSet.contains(view.getTransitionName())) {
|
||||
views.add(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the shared elements of an unoptimized fragment transaction's transition.
|
||||
* This retrieves the shared elements of the incoming fragments, and schedules capturing
|
||||
|
||||
Reference in New Issue
Block a user