Activity Transition: fix quick back after enter.
Bug 19105460 When an Activity Transition was receiving an exit call immediately after the enter, the transition for the enter was still in progress. TransitionManager does not allow multiple transitions to work at once, so the enter transition would run, but the exit did not. This CL detects when the enter transition is still pending and tells the ActivityTransitionState to delay one frame so that the enter can finish its required work prior to starting the exit transition. Change-Id: I1b40f1e41d61a67da3fd672419ea321e7d0496da
This commit is contained in:
@@ -799,6 +799,15 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
|
||||
mIsStartingTransition = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels any pending transitions and returns true if there is a transition is in
|
||||
* the middle of starting.
|
||||
*/
|
||||
protected boolean cancelPendingTransitions() {
|
||||
mPendingTransition = null;
|
||||
return mIsStartingTransition;
|
||||
}
|
||||
|
||||
protected void moveSharedElementsToOverlay() {
|
||||
if (mWindow == null || !mWindow.getSharedElementsUseOverlay()) {
|
||||
return;
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.util.ArrayMap;
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -252,7 +253,7 @@ class ActivityTransitionState {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean startExitBackTransition(Activity activity) {
|
||||
public boolean startExitBackTransition(final Activity activity) {
|
||||
if (mEnteringNames == null) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -260,10 +261,11 @@ class ActivityTransitionState {
|
||||
mHasExited = true;
|
||||
Transition enterViewsTransition = null;
|
||||
ViewGroup decor = null;
|
||||
boolean delayExitBack = false;
|
||||
if (mEnterTransitionCoordinator != null) {
|
||||
enterViewsTransition = mEnterTransitionCoordinator.getEnterViewsTransition();
|
||||
decor = mEnterTransitionCoordinator.getDecor();
|
||||
mEnterTransitionCoordinator.cancelEnter();
|
||||
delayExitBack = mEnterTransitionCoordinator.cancelEnter();
|
||||
mEnterTransitionCoordinator = null;
|
||||
if (enterViewsTransition != null && decor != null) {
|
||||
enterViewsTransition.pause(decor);
|
||||
@@ -275,7 +277,23 @@ class ActivityTransitionState {
|
||||
if (enterViewsTransition != null && decor != null) {
|
||||
enterViewsTransition.resume(decor);
|
||||
}
|
||||
mReturnExitCoordinator.startExit(activity.mResultCode, activity.mResultData);
|
||||
if (delayExitBack && decor != null) {
|
||||
final ViewGroup finalDecor = decor;
|
||||
decor.getViewTreeObserver().addOnPreDrawListener(
|
||||
new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
finalDecor.getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
if (mReturnExitCoordinator != null) {
|
||||
mReturnExitCoordinator.startExit(activity.mResultCode,
|
||||
activity.mResultData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mReturnExitCoordinator.startExit(activity.mResultCode, activity.mResultData);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package android.app;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.ResultReceiver;
|
||||
@@ -565,7 +564,12 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
|
||||
clearState();
|
||||
}
|
||||
|
||||
public void cancelEnter() {
|
||||
/**
|
||||
* Cancels the enter transition.
|
||||
* @return True if the enter transition is still pending capturing the target state. If so,
|
||||
* any transition started on the decor will do nothing.
|
||||
*/
|
||||
public boolean cancelEnter() {
|
||||
setGhostVisibility(View.INVISIBLE);
|
||||
mHasStopped = true;
|
||||
mIsCanceled = true;
|
||||
@@ -576,6 +580,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
|
||||
}
|
||||
mActivity = null;
|
||||
clearState();
|
||||
return super.cancelPendingTransitions();
|
||||
}
|
||||
|
||||
private void makeOpaque() {
|
||||
|
||||
Reference in New Issue
Block a user