diff options
| -rw-r--r-- | core/java/android/app/ActivityTransitionCoordinator.java | 116 | ||||
| -rw-r--r-- | core/java/android/app/EnterTransitionCoordinator.java | 30 |
2 files changed, 102 insertions, 44 deletions
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java index d61105872061..ef7ef487dd34 100644 --- a/core/java/android/app/ActivityTransitionCoordinator.java +++ b/core/java/android/app/ActivityTransitionCoordinator.java @@ -206,6 +206,8 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { private ArrayList<GhostViewListeners> mGhostViewListeners = new ArrayList<GhostViewListeners>(); private ArrayMap<View, Float> mOriginalAlphas = new ArrayMap<View, Float>(); + final private ArrayList<View> mRootSharedElements = new ArrayList<View>(); + private ArrayList<Matrix> mSharedElementParentMatrices; public ActivityTransitionCoordinator(Window window, ArrayList<String> allSharedElementNames, @@ -222,15 +224,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { if (mListener != null) { mListener.onMapSharedElements(mAllSharedElementNames, sharedElements); } - int numSharedElements = sharedElements.size(); - for (int i = 0; i < numSharedElements; i++) { - View sharedElement = sharedElements.valueAt(i); - String name = sharedElements.keyAt(i); - if (sharedElement != null && sharedElement.isAttachedToWindow() && name != null) { - mSharedElements.add(sharedElement); - mSharedElementNames.add(name); - } - } + setSharedElements(sharedElements); if (getViewsTransition() != null && mTransitioningViews != null) { ViewGroup decorView = getDecor(); if (decorView != null) { @@ -241,6 +235,58 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { setEpicenter(); } + /** + * Iterates over the shared elements and adds them to the members in order. + * Shared elements that are nested in other shared elements are placed after the + * elements that they are nested in. This means that layout ordering can be done + * from first to last. + * + * @param sharedElements The map of transition names to shared elements to set into + * the member fields. + */ + private void setSharedElements(ArrayMap<String, View> sharedElements) { + boolean isFirstRun = true; + while (!sharedElements.isEmpty()) { + final int numSharedElements = sharedElements.size(); + for (int i = numSharedElements - 1; i >= 0; i--) { + final View view = sharedElements.valueAt(i); + final String name = sharedElements.keyAt(i); + if (isFirstRun && (view == null || !view.isAttachedToWindow() || name == null)) { + sharedElements.removeAt(i); + } else { + if (!isNested(view, sharedElements)) { + mSharedElementNames.add(name); + mSharedElements.add(view); + sharedElements.removeAt(i); + if (isFirstRun) { + // We need to keep track which shared elements are roots + // and which are nested. + mRootSharedElements.add(view); + } + } + } + } + isFirstRun = false; + } + } + + /** + * Returns true when view is nested in any of the values of sharedElements. + */ + private static boolean isNested(View view, ArrayMap<String, View> sharedElements) { + ViewParent parent = view.getParent(); + boolean isNested = false; + while (parent instanceof View) { + View parentView = (View) parent; + if (sharedElements.containsValue(parentView)) { + isNested = true; + break; + } + parent = parentView.getParent(); + } + return isNested; + } + protected void stripOffscreenViews() { if (mTransitioningViews == null) { return; @@ -456,11 +502,50 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { view.layout(x, y, x + width, y + height); } - protected void getSharedElementParentMatrix(View view, Matrix matrix) { - // Find the location in the view's parent - ViewGroup parent = (ViewGroup) view.getParent(); - matrix.reset(); - parent.transformMatrixToLocal(matrix); + private void setSharedElementMatrices() { + int numSharedElements = mSharedElements.size(); + if (numSharedElements > 0) { + mSharedElementParentMatrices = new ArrayList<Matrix>(numSharedElements); + } + for (int i = 0; i < numSharedElements; i++) { + View view = mSharedElements.get(i); + + // Find the location in the view's parent + ViewGroup parent = (ViewGroup) view.getParent(); + Matrix matrix = new Matrix(); + parent.transformMatrixToLocal(matrix); + + mSharedElementParentMatrices.add(matrix); + } + } + + private void getSharedElementParentMatrix(View view, Matrix matrix) { + final boolean isNestedInOtherSharedElement = !mRootSharedElements.contains(view); + final boolean useParentMatrix; + if (isNestedInOtherSharedElement) { + useParentMatrix = true; + } else { + final int index = mSharedElementParentMatrices == null ? -1 + : mSharedElements.indexOf(view); + if (index < 0) { + useParentMatrix = true; + } else { + // The indices of mSharedElementParentMatrices matches the + // mSharedElement matrices. + Matrix parentMatrix = mSharedElementParentMatrices.get(index); + matrix.set(parentMatrix); + useParentMatrix = false; + } + } + if (useParentMatrix) { + matrix.reset(); + ViewParent viewParent = view.getParent(); + if (viewParent instanceof ViewGroup) { + // Find the location in the view's parent + ViewGroup parent = (ViewGroup) viewParent; + parent.transformMatrixToLocal(matrix); + } + } } protected ArrayList<SharedElementOriginalState> setSharedElementState( @@ -614,6 +699,8 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { mResultReceiver = null; mPendingTransition = null; mListener = null; + mRootSharedElements.clear(); + mSharedElementParentMatrices = null; } protected long getFadeDuration() { @@ -714,6 +801,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { if (!mWindow.getSharedElementsUseOverlay()) { return; } + setSharedElementMatrices(); int numSharedElements = mSharedElements.size(); ViewGroup decor = getDecor(); if (decor != null) { diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java index add67f2ec8a5..e785215559f7 100644 --- a/core/java/android/app/EnterTransitionCoordinator.java +++ b/core/java/android/app/EnterTransitionCoordinator.java @@ -57,7 +57,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { private boolean mIsViewsTransitionStarted; private boolean mIsViewsTransitionComplete; private boolean mIsSharedElementTransitionComplete; - private ArrayList<Matrix> mSharedElementParentMatrices; private Transition mEnterViewsTransition; public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver, @@ -122,7 +121,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { if (mIsReturning) { sendSharedElementDestination(); } else { - setSharedElementMatrices(); moveSharedElementsToOverlay(); } if (mSharedElementsBundle != null) { @@ -194,7 +192,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { } if (allReady) { Bundle state = captureSharedElementState(); - setSharedElementMatrices(); moveSharedElementsToOverlay(); mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state); } else if (decorView != null) { @@ -205,7 +202,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { decorView.getViewTreeObserver().removeOnPreDrawListener(this); if (mResultReceiver != null) { Bundle state = captureSharedElementState(); - setSharedElementMatrices(); moveSharedElementsToOverlay(); mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state); } @@ -634,30 +630,4 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { }); } - private void setSharedElementMatrices() { - int numSharedElements = mSharedElements.size(); - if (numSharedElements > 0) { - mSharedElementParentMatrices = new ArrayList<Matrix>(numSharedElements); - } - for (int i = 0; i < numSharedElements; i++) { - View view = mSharedElements.get(i); - - // Find the location in the view's parent - ViewGroup parent = (ViewGroup) view.getParent(); - Matrix matrix = new Matrix(); - parent.transformMatrixToLocal(matrix); - - mSharedElementParentMatrices.add(matrix); - } - } - - @Override - protected void getSharedElementParentMatrix(View view, Matrix matrix) { - int index = mSharedElementParentMatrices == null ? -1 : mSharedElements.indexOf(view); - if (index < 0) { - super.getSharedElementParentMatrix(view, matrix); - } else { - matrix.set(mSharedElementParentMatrices.get(index)); - } - } } |