diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java index e222fee6e409e..abb098f05184d 100644 --- a/core/java/android/app/BackStackRecord.java +++ b/core/java/android/app/BackStackRecord.java @@ -534,6 +534,12 @@ final class BackStackRecord extends FragmentTransaction implements if (mSharedElementSourceNames == null) { mSharedElementSourceNames = new ArrayList(); mSharedElementTargetNames = new ArrayList(); + } 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); diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java index 088fd08d97a87..33244481c2893 100644 --- a/core/java/android/app/FragmentTransition.java +++ b/core/java/android/app/FragmentTransition.java @@ -367,9 +367,11 @@ class FragmentTransition { } if (exitingViews != null) { - ArrayList tempExiting = new ArrayList<>(); - tempExiting.add(nonExistentView); - replaceTargets(exitTransition, exitingViews, tempExiting); + if (exitTransition != null) { + ArrayList 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 views, + ArrayMap sharedElements, Collection 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