From f1abef6fc2194e72af521202ee4b17c10e03c935 Mon Sep 17 00:00:00 2001 From: George Mount Date: Mon, 22 Sep 2014 13:58:21 -0700 Subject: [PATCH] Force transitioning views to be visible when transition interrupted. Bug 17553034 When an Activity Transition was interrupted prior to starting the enter transition, the views were not being made visible. Override the return ActivityOptions if interrupted so that the entering activity doesn't launch with a transition when coming back from recents. Change-Id: Id4e00c7bb138babfee4de71247a9df4431376e21 --- core/java/android/app/ActivityTransitionState.java | 14 ++++++- .../android/app/EnterTransitionCoordinator.java | 43 ++++++++++++++++++---- .../android/app/ExitTransitionCoordinator.java | 21 ++++++++--- 3 files changed, 63 insertions(+), 15 deletions(-) diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java index bc2e6ca5f57f..555d20bba99a 100644 --- a/core/java/android/app/ActivityTransitionState.java +++ b/core/java/android/app/ActivityTransitionState.java @@ -67,6 +67,12 @@ class ActivityTransitionState { private ExitTransitionCoordinator mCalledExitCoordinator; /** + * The ExitTransitionCoordinator used to return to a previous Activity when called with + * {@link android.app.Activity#finishAfterTransition()}. + */ + private ExitTransitionCoordinator mReturnExitCoordinator; + + /** * We must be able to cancel entering transitions to stop changing the Window to * opaque when we exit before making the Window opaque. */ @@ -218,6 +224,10 @@ class ActivityTransitionState { mEnterTransitionCoordinator.stop(); mEnterTransitionCoordinator = null; } + if (mReturnExitCoordinator != null) { + mReturnExitCoordinator.stop(); + mReturnExitCoordinator = null; + } } public void onResume() { @@ -260,12 +270,12 @@ class ActivityTransitionState { } } - ExitTransitionCoordinator exitCoordinator = + mReturnExitCoordinator = new ExitTransitionCoordinator(activity, mEnteringNames, null, null, true); if (enterViewsTransition != null && decor != null) { enterViewsTransition.resume(decor); } - exitCoordinator.startExit(activity.mResultCode, activity.mResultData); + mReturnExitCoordinator.startExit(activity.mResultCode, activity.mResultData); } return true; } diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java index 216d6bab38ad..add67f2ec8a5 100644 --- a/core/java/android/app/EnterTransitionCoordinator.java +++ b/core/java/android/app/EnterTransitionCoordinator.java @@ -30,6 +30,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroupOverlay; import android.view.ViewTreeObserver; +import android.view.Window; import java.util.ArrayList; @@ -265,10 +266,14 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { } protected void prepareEnter() { + ViewGroup decorView = getDecor(); + if (mActivity == null || decorView == null) { + return; + } mActivity.overridePendingTransition(0, 0); if (!mIsReturning) { mWasOpaque = mActivity.convertToTranslucent(null, null); - Drawable background = getDecor().getBackground(); + Drawable background = decorView.getBackground(); if (background != null) { getWindow().setBackgroundDrawable(null); background = background.mutate(); @@ -282,18 +287,26 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { @Override protected Transition getViewsTransition() { + Window window = getWindow(); + if (window == null) { + return null; + } if (mIsReturning) { - return getWindow().getReenterTransition(); + return window.getReenterTransition(); } else { - return getWindow().getEnterTransition(); + return window.getEnterTransition(); } } protected Transition getSharedElementTransition() { + Window window = getWindow(); + if (window == null) { + return null; + } if (mIsReturning) { - return getWindow().getSharedElementReenterTransition(); + return window.getSharedElementReenterTransition(); } else { - return getWindow().getSharedElementEnterTransition(); + return window.getSharedElementEnterTransition(); } } @@ -518,15 +531,29 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { } public void stop() { - makeOpaque(); - mIsCanceled = true; - mResultReceiver = null; + // Restore the background to its previous state since the + // Activity is stopping. if (mBackgroundAnimator != null) { mBackgroundAnimator.end(); mBackgroundAnimator = null; + } else if (mWasOpaque) { + ViewGroup decorView = getDecor(); + if (decorView != null) { + Drawable drawable = decorView.getBackground(); + if (drawable != null) { + drawable.setAlpha(1); + } + } } + makeOpaque(); + mIsCanceled = true; + mResultReceiver = null; mActivity = null; moveSharedElementsFromOverlay(); + if (mTransitioningViews != null) { + showViews(mTransitioningViews, true); + } + showViews(mSharedElements, true); clearState(); } diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java index d4d3eda91e75..dd3df47942cc 100644 --- a/core/java/android/app/ExitTransitionCoordinator.java +++ b/core/java/android/app/ExitTransitionCoordinator.java @@ -255,6 +255,16 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { } } + public void stop() { + if (mIsReturning && mActivity != null) { + // Override the previous ActivityOptions. We don't want the + // activity to have options since we're essentially canceling the + // transition and finishing right now. + mActivity.convertToTranslucent(null, null); + finish(); + } + } + private void startExitTransition() { Transition transition = getExitTransition(); ViewGroup decorView = getDecor(); @@ -425,13 +435,14 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { private void finish() { stopCancel(); - mActivity.mActivityTransitionState.clear(); + if (mActivity != null) { + mActivity.mActivityTransitionState.clear(); + mActivity.finish(); + mActivity.overridePendingTransition(0, 0); + mActivity = null; + } // Clear the state so that we can't hold any references accidentally and leak memory. - mHandler.removeMessages(MSG_CANCEL); mHandler = null; - mActivity.finish(); - mActivity.overridePendingTransition(0, 0); - mActivity = null; mSharedElementBundle = null; if (mBackgroundAnimator != null) { mBackgroundAnimator.cancel(); -- 2.11.0