Loading core/java/android/app/ActivityTransitionCoordinator.java +26 −1 Original line number Diff line number Diff line Loading @@ -206,6 +206,9 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { protected ResultReceiver mResultReceiver; final private FixedEpicenterCallback mEpicenterCallback = new FixedEpicenterCallback(); final protected boolean mIsReturning; private Runnable mPendingTransition; private boolean mIsStartingTransition; public ActivityTransitionCoordinator(Window window, ArrayList<String> allSharedElementNames, Loading Loading @@ -523,7 +526,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { * @param transitionArgs Bundle to store shared element placement information. * @param tempBounds A temporary Rect for capturing the current location of views. */ private static void captureSharedElementState(View view, String name, Bundle transitionArgs, protected static void captureSharedElementState(View view, String name, Bundle transitionArgs, Rect tempBounds) { Bundle sharedElementBundle = new Bundle(); tempBounds.set(0, 0, view.getWidth(), view.getHeight()); Loading Loading @@ -559,6 +562,28 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { transitionArgs.putBundle(name, sharedElementBundle); } protected void startTransition(Runnable runnable) { if (mIsStartingTransition) { mPendingTransition = runnable; } else { mIsStartingTransition = true; runnable.run(); } } protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter { @Override public void onTransitionStart(Transition transition) { mIsStartingTransition = false; Runnable pending = mPendingTransition; mPendingTransition = null; if (pending != null) { startTransition(pending); } } } private static int scaleTypeToInt(ImageView.ScaleType scaleType) { for (int i = 0; i < SCALE_TYPE_VALUES.length; i++) { if (scaleType == SCALE_TYPE_VALUES[i]) { Loading core/java/android/app/EnterTransitionCoordinator.java +12 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,16 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { private void sendSharedElementDestination() { ViewGroup decor = getDecor(); if (!decor.isLayoutRequested()) { boolean allReady = !decor.isLayoutRequested(); if (allReady) { for (int i = 0; i < mSharedElements.size(); i++) { if (mSharedElements.get(i).isLayoutRequested()) { allReady = false; break; } } } if (allReady) { Bundle state = captureSharedElementState(); mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state); } else { Loading @@ -115,6 +124,8 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { @Override public boolean onPreDraw() { getDecor().getViewTreeObserver().removeOnPreDrawListener(this); Bundle state = captureSharedElementState(); mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state); return true; } }); Loading core/java/android/app/ExitTransitionCoordinator.java +99 −36 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Intent; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; Loading @@ -27,6 +28,7 @@ import android.os.Message; import android.transition.Transition; import android.transition.TransitionManager; import android.view.View; import android.view.ViewGroupOverlay; import android.view.ViewTreeObserver; import java.util.ArrayList; Loading Loading @@ -60,10 +62,10 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { private boolean mIsHidden; private boolean mExitTransitionStarted; private Bundle mExitSharedElementBundle; private ArrayList<View> mSharedElementSnapshots; public ExitTransitionCoordinator(Activity activity, ArrayList<String> names, ArrayList<String> accepted, ArrayList<String> mapped, boolean isReturning) { super(activity.getWindow(), names, accepted, mapped, getListener(activity, isReturning), Loading Loading @@ -106,30 +108,81 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { break; case MSG_SHARED_ELEMENT_DESTINATION: mExitSharedElementBundle = resultData; if (mExitTransitionStarted) { sharedElementExitBack(); break; } } private void sharedElementExitBack() { if (!mSharedElements.isEmpty() && getSharedElementTransition() != null) { startTransition(new Runnable() { public void run() { startSharedElementExit(); } break; }); } } private void startSharedElementExit() { if (!mSharedElements.isEmpty() && getSharedElementTransition() != null) { Transition transition = getSharedElementExitTransition(); TransitionManager.beginDelayedTransition(getDecor(), transition); ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle, final ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle, mSharedElementNames); mSharedElementSnapshots = createSnapshots(mExitSharedElementBundle, mSharedElementNames); transition.addListener(new Transition.TransitionListenerAdapter() { @Override public void onTransitionEnd(Transition transition) { setViewVisibility(mSharedElements, View.INVISIBLE); ViewGroupOverlay overlay = getDecor().getOverlay(); for (int i = 0; i < mSharedElementSnapshots.size(); i++) { overlay.add(mSharedElementSnapshots.get(i)); } } }); getDecor().getViewTreeObserver() .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getDecor().getViewTreeObserver().removeOnPreDrawListener(this); setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots); return true; } }); TransitionManager.beginDelayedTransition(getDecor(), transition); getDecor().invalidate(); } private static ArrayList<View> copySnapshots(ArrayList<View> snapshots) { ArrayList<View> copy = new ArrayList<View>(snapshots.size()); for (int i = 0; i < snapshots.size(); i++) { View view = snapshots.get(i); View viewCopy = new View(view.getContext()); viewCopy.setBackground(view.getBackground()); copy.add(viewCopy); } return copy; } private void hideSharedElements() { if (!mIsHidden) { setViewVisibility(mSharedElements, View.INVISIBLE); } if (mSharedElementSnapshots != null) { ViewGroupOverlay overlay = getDecor().getOverlay(); for (int i = 0; i < mSharedElementSnapshots.size(); i++) { overlay.remove(mSharedElementSnapshots.get(i)); } mSharedElementSnapshots = null; } finishIfNecessary(); } public void startExit() { startTransition(new Runnable() { @Override public void run() { beginTransitions(); } }); setViewVisibility(mTransitioningViews, View.INVISIBLE); } Loading Loading @@ -159,29 +212,25 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { } } }, options); startTransition(new Runnable() { @Override public void run() { startExitTransition(); } }); } private void startExitTransition() { Transition sharedElementTransition = mSharedElements.isEmpty() ? null : getSharedElementTransition(); if (sharedElementTransition == null) { sharedElementTransitionComplete(); } Transition transition = mergeTransitions(sharedElementTransition, getExitTransition()); if (transition == null) { mExitTransitionStarted = true; } else { Transition transition = mergeTransitions(sharedElementTransition, getExitTransition()); if (transition != null) { TransitionManager.beginDelayedTransition(getDecor(), transition); setViewVisibility(mTransitioningViews, View.INVISIBLE); getDecor().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getDecor().getViewTreeObserver().removeOnPreDrawListener(this); mExitTransitionStarted = true; if (mExitSharedElementBundle != null) { startSharedElementExit(); } notifyComplete(); return true; } }); } } Loading Loading @@ -212,7 +261,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { if (viewsTransition == null) { exitTransitionComplete(); } else { viewsTransition.addListener(new Transition.TransitionListenerAdapter() { viewsTransition.addListener(new ContinueTransitionListener() { @Override public void onTransitionEnd(Transition transition) { exitTransitionComplete(); Loading @@ -238,7 +287,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { if (sharedElementTransition == null) { sharedElementTransitionComplete(); } else { sharedElementTransition.addListener(new Transition.TransitionListenerAdapter() { sharedElementTransition.addListener(new ContinueTransitionListener() { @Override public void onTransitionEnd(Transition transition) { sharedElementTransitionComplete(); Loading @@ -257,7 +306,6 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { Transition viewsTransition = getExitTransition(); Transition transition = mergeTransitions(sharedElementTransition, viewsTransition); mExitTransitionStarted = true; if (transition != null) { TransitionManager.beginDelayedTransition(getDecor(), transition); } Loading @@ -269,15 +317,31 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { } protected boolean isReadyToNotify() { return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady && mExitTransitionStarted; return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady; } private void sharedElementTransitionComplete() { mSharedElementBundle = captureSharedElementState(); mSharedElementBundle = mExitSharedElementBundle == null ? captureSharedElementState() : captureExitSharedElementsState(); notifyComplete(); } private Bundle captureExitSharedElementsState() { Bundle bundle = new Bundle(); Rect bounds = new Rect(); for (int i = 0; i < mSharedElementNames.size(); i++) { String name = mSharedElementNames.get(i); Bundle sharedElementState = mExitSharedElementBundle.getBundle(name); if (sharedElementState != null) { bundle.putBundle(name, sharedElementState); } else { View view = mSharedElements.get(i); captureSharedElementState(view, name, bundle, bounds); } } return bundle; } protected void notifyComplete() { if (isReadyToNotify()) { if (!mSharedElementNotified) { Loading @@ -294,8 +358,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { } private void finishIfNecessary() { if (mIsReturning && mExitNotified && mActivity != null && (mSharedElements.isEmpty() || mSharedElements.get(0).getVisibility() == View.INVISIBLE)) { if (mIsReturning && mExitNotified && mActivity != null && mSharedElementSnapshots == null) { mActivity.finish(); mActivity.overridePendingTransition(0, 0); mActivity = null; Loading Loading
core/java/android/app/ActivityTransitionCoordinator.java +26 −1 Original line number Diff line number Diff line Loading @@ -206,6 +206,9 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { protected ResultReceiver mResultReceiver; final private FixedEpicenterCallback mEpicenterCallback = new FixedEpicenterCallback(); final protected boolean mIsReturning; private Runnable mPendingTransition; private boolean mIsStartingTransition; public ActivityTransitionCoordinator(Window window, ArrayList<String> allSharedElementNames, Loading Loading @@ -523,7 +526,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { * @param transitionArgs Bundle to store shared element placement information. * @param tempBounds A temporary Rect for capturing the current location of views. */ private static void captureSharedElementState(View view, String name, Bundle transitionArgs, protected static void captureSharedElementState(View view, String name, Bundle transitionArgs, Rect tempBounds) { Bundle sharedElementBundle = new Bundle(); tempBounds.set(0, 0, view.getWidth(), view.getHeight()); Loading Loading @@ -559,6 +562,28 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { transitionArgs.putBundle(name, sharedElementBundle); } protected void startTransition(Runnable runnable) { if (mIsStartingTransition) { mPendingTransition = runnable; } else { mIsStartingTransition = true; runnable.run(); } } protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter { @Override public void onTransitionStart(Transition transition) { mIsStartingTransition = false; Runnable pending = mPendingTransition; mPendingTransition = null; if (pending != null) { startTransition(pending); } } } private static int scaleTypeToInt(ImageView.ScaleType scaleType) { for (int i = 0; i < SCALE_TYPE_VALUES.length; i++) { if (scaleType == SCALE_TYPE_VALUES[i]) { Loading
core/java/android/app/EnterTransitionCoordinator.java +12 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,16 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { private void sendSharedElementDestination() { ViewGroup decor = getDecor(); if (!decor.isLayoutRequested()) { boolean allReady = !decor.isLayoutRequested(); if (allReady) { for (int i = 0; i < mSharedElements.size(); i++) { if (mSharedElements.get(i).isLayoutRequested()) { allReady = false; break; } } } if (allReady) { Bundle state = captureSharedElementState(); mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state); } else { Loading @@ -115,6 +124,8 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { @Override public boolean onPreDraw() { getDecor().getViewTreeObserver().removeOnPreDrawListener(this); Bundle state = captureSharedElementState(); mResultReceiver.send(MSG_SHARED_ELEMENT_DESTINATION, state); return true; } }); Loading
core/java/android/app/ExitTransitionCoordinator.java +99 −36 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Intent; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; Loading @@ -27,6 +28,7 @@ import android.os.Message; import android.transition.Transition; import android.transition.TransitionManager; import android.view.View; import android.view.ViewGroupOverlay; import android.view.ViewTreeObserver; import java.util.ArrayList; Loading Loading @@ -60,10 +62,10 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { private boolean mIsHidden; private boolean mExitTransitionStarted; private Bundle mExitSharedElementBundle; private ArrayList<View> mSharedElementSnapshots; public ExitTransitionCoordinator(Activity activity, ArrayList<String> names, ArrayList<String> accepted, ArrayList<String> mapped, boolean isReturning) { super(activity.getWindow(), names, accepted, mapped, getListener(activity, isReturning), Loading Loading @@ -106,30 +108,81 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { break; case MSG_SHARED_ELEMENT_DESTINATION: mExitSharedElementBundle = resultData; if (mExitTransitionStarted) { sharedElementExitBack(); break; } } private void sharedElementExitBack() { if (!mSharedElements.isEmpty() && getSharedElementTransition() != null) { startTransition(new Runnable() { public void run() { startSharedElementExit(); } break; }); } } private void startSharedElementExit() { if (!mSharedElements.isEmpty() && getSharedElementTransition() != null) { Transition transition = getSharedElementExitTransition(); TransitionManager.beginDelayedTransition(getDecor(), transition); ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle, final ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle, mSharedElementNames); mSharedElementSnapshots = createSnapshots(mExitSharedElementBundle, mSharedElementNames); transition.addListener(new Transition.TransitionListenerAdapter() { @Override public void onTransitionEnd(Transition transition) { setViewVisibility(mSharedElements, View.INVISIBLE); ViewGroupOverlay overlay = getDecor().getOverlay(); for (int i = 0; i < mSharedElementSnapshots.size(); i++) { overlay.add(mSharedElementSnapshots.get(i)); } } }); getDecor().getViewTreeObserver() .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getDecor().getViewTreeObserver().removeOnPreDrawListener(this); setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots); return true; } }); TransitionManager.beginDelayedTransition(getDecor(), transition); getDecor().invalidate(); } private static ArrayList<View> copySnapshots(ArrayList<View> snapshots) { ArrayList<View> copy = new ArrayList<View>(snapshots.size()); for (int i = 0; i < snapshots.size(); i++) { View view = snapshots.get(i); View viewCopy = new View(view.getContext()); viewCopy.setBackground(view.getBackground()); copy.add(viewCopy); } return copy; } private void hideSharedElements() { if (!mIsHidden) { setViewVisibility(mSharedElements, View.INVISIBLE); } if (mSharedElementSnapshots != null) { ViewGroupOverlay overlay = getDecor().getOverlay(); for (int i = 0; i < mSharedElementSnapshots.size(); i++) { overlay.remove(mSharedElementSnapshots.get(i)); } mSharedElementSnapshots = null; } finishIfNecessary(); } public void startExit() { startTransition(new Runnable() { @Override public void run() { beginTransitions(); } }); setViewVisibility(mTransitioningViews, View.INVISIBLE); } Loading Loading @@ -159,29 +212,25 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { } } }, options); startTransition(new Runnable() { @Override public void run() { startExitTransition(); } }); } private void startExitTransition() { Transition sharedElementTransition = mSharedElements.isEmpty() ? null : getSharedElementTransition(); if (sharedElementTransition == null) { sharedElementTransitionComplete(); } Transition transition = mergeTransitions(sharedElementTransition, getExitTransition()); if (transition == null) { mExitTransitionStarted = true; } else { Transition transition = mergeTransitions(sharedElementTransition, getExitTransition()); if (transition != null) { TransitionManager.beginDelayedTransition(getDecor(), transition); setViewVisibility(mTransitioningViews, View.INVISIBLE); getDecor().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getDecor().getViewTreeObserver().removeOnPreDrawListener(this); mExitTransitionStarted = true; if (mExitSharedElementBundle != null) { startSharedElementExit(); } notifyComplete(); return true; } }); } } Loading Loading @@ -212,7 +261,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { if (viewsTransition == null) { exitTransitionComplete(); } else { viewsTransition.addListener(new Transition.TransitionListenerAdapter() { viewsTransition.addListener(new ContinueTransitionListener() { @Override public void onTransitionEnd(Transition transition) { exitTransitionComplete(); Loading @@ -238,7 +287,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { if (sharedElementTransition == null) { sharedElementTransitionComplete(); } else { sharedElementTransition.addListener(new Transition.TransitionListenerAdapter() { sharedElementTransition.addListener(new ContinueTransitionListener() { @Override public void onTransitionEnd(Transition transition) { sharedElementTransitionComplete(); Loading @@ -257,7 +306,6 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { Transition viewsTransition = getExitTransition(); Transition transition = mergeTransitions(sharedElementTransition, viewsTransition); mExitTransitionStarted = true; if (transition != null) { TransitionManager.beginDelayedTransition(getDecor(), transition); } Loading @@ -269,15 +317,31 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { } protected boolean isReadyToNotify() { return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady && mExitTransitionStarted; return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady; } private void sharedElementTransitionComplete() { mSharedElementBundle = captureSharedElementState(); mSharedElementBundle = mExitSharedElementBundle == null ? captureSharedElementState() : captureExitSharedElementsState(); notifyComplete(); } private Bundle captureExitSharedElementsState() { Bundle bundle = new Bundle(); Rect bounds = new Rect(); for (int i = 0; i < mSharedElementNames.size(); i++) { String name = mSharedElementNames.get(i); Bundle sharedElementState = mExitSharedElementBundle.getBundle(name); if (sharedElementState != null) { bundle.putBundle(name, sharedElementState); } else { View view = mSharedElements.get(i); captureSharedElementState(view, name, bundle, bounds); } } return bundle; } protected void notifyComplete() { if (isReadyToNotify()) { if (!mSharedElementNotified) { Loading @@ -294,8 +358,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { } private void finishIfNecessary() { if (mIsReturning && mExitNotified && mActivity != null && (mSharedElements.isEmpty() || mSharedElements.get(0).getVisibility() == View.INVISIBLE)) { if (mIsReturning && mExitNotified && mActivity != null && mSharedElementSnapshots == null) { mActivity.finish(); mActivity.overridePendingTransition(0, 0); mActivity = null; Loading