ExitTransitionCoordinator.java revision 6558056e8fccc32f9e1dc59e46d09f8d916b7538
131a217290cf376d0573fc36e21c8940987485019George Mount/*
231a217290cf376d0573fc36e21c8940987485019George Mount * Copyright (C) 2014 The Android Open Source Project
331a217290cf376d0573fc36e21c8940987485019George Mount *
431a217290cf376d0573fc36e21c8940987485019George Mount * Licensed under the Apache License, Version 2.0 (the "License");
531a217290cf376d0573fc36e21c8940987485019George Mount * you may not use this file except in compliance with the License.
631a217290cf376d0573fc36e21c8940987485019George Mount * You may obtain a copy of the License at
731a217290cf376d0573fc36e21c8940987485019George Mount *
831a217290cf376d0573fc36e21c8940987485019George Mount *      http://www.apache.org/licenses/LICENSE-2.0
931a217290cf376d0573fc36e21c8940987485019George Mount *
1031a217290cf376d0573fc36e21c8940987485019George Mount * Unless required by applicable law or agreed to in writing, software
1131a217290cf376d0573fc36e21c8940987485019George Mount * distributed under the License is distributed on an "AS IS" BASIS,
1231a217290cf376d0573fc36e21c8940987485019George Mount * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331a217290cf376d0573fc36e21c8940987485019George Mount * See the License for the specific language governing permissions and
1431a217290cf376d0573fc36e21c8940987485019George Mount * limitations under the License.
1531a217290cf376d0573fc36e21c8940987485019George Mount */
1631a217290cf376d0573fc36e21c8940987485019George Mountpackage android.app;
1731a217290cf376d0573fc36e21c8940987485019George Mount
1862ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.animation.Animator;
1962ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.animation.AnimatorListenerAdapter;
2062ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.animation.ObjectAnimator;
2162ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.content.Intent;
2285b764e22babfe5508286fbad5d7fee12345704fCraig Mautnerimport android.graphics.Color;
237bf379c8af399626d5b8b568fe1d4f96f56badccDake Guimport android.graphics.Matrix;
247bf379c8af399626d5b8b568fe1d4f96f56badccDake Guimport android.graphics.RectF;
2562ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.graphics.drawable.ColorDrawable;
268cab50afda0d8485436f72a93d668697f549d3b3George Mountimport android.graphics.drawable.Drawable;
2731a217290cf376d0573fc36e21c8940987485019George Mountimport android.os.Bundle;
2862ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.os.Handler;
2962ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.os.Message;
3031a217290cf376d0573fc36e21c8940987485019George Mountimport android.transition.Transition;
3162ab9b78b77b7dd851c47115f4d8d7611d657585George Mountimport android.transition.TransitionManager;
3231a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.View;
33e678ab686643127b4b297ae7a1e4869b4cfc6e53George Mountimport android.view.ViewGroup;
34c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.view.ViewTreeObserver;
3531a217290cf376d0573fc36e21c8940987485019George Mount
3631a217290cf376d0573fc36e21c8940987485019George Mountimport java.util.ArrayList;
3731a217290cf376d0573fc36e21c8940987485019George Mount
3831a217290cf376d0573fc36e21c8940987485019George Mount/**
3931a217290cf376d0573fc36e21c8940987485019George Mount * This ActivityTransitionCoordinator is created in ActivityOptions#makeSceneTransitionAnimation
4031a217290cf376d0573fc36e21c8940987485019George Mount * to govern the exit of the Scene and the shared elements when calling an Activity as well as
4131a217290cf376d0573fc36e21c8940987485019George Mount * the reentry of the Scene when coming back from the called Activity.
4231a217290cf376d0573fc36e21c8940987485019George Mount */
4331a217290cf376d0573fc36e21c8940987485019George Mountclass ExitTransitionCoordinator extends ActivityTransitionCoordinator {
4431a217290cf376d0573fc36e21c8940987485019George Mount    private static final String TAG = "ExitTransitionCoordinator";
458cab50afda0d8485436f72a93d668697f549d3b3George Mount    private static final long MAX_WAIT_MS = 1000;
4631a217290cf376d0573fc36e21c8940987485019George Mount
4762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mExitComplete;
4831a217290cf376d0573fc36e21c8940987485019George Mount
4962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private Bundle mSharedElementBundle;
5031a217290cf376d0573fc36e21c8940987485019George Mount
5162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mExitNotified;
5231a217290cf376d0573fc36e21c8940987485019George Mount
5362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mSharedElementNotified;
5431a217290cf376d0573fc36e21c8940987485019George Mount
5562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private Activity mActivity;
5631a217290cf376d0573fc36e21c8940987485019George Mount
5762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mIsBackgroundReady;
5862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
5962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private boolean mIsCanceled;
6062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
6162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private Handler mHandler;
6262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
638cab50afda0d8485436f72a93d668697f549d3b3George Mount    private ObjectAnimator mBackgroundAnimator;
648cab50afda0d8485436f72a93d668697f549d3b3George Mount
658cab50afda0d8485436f72a93d668697f549d3b3George Mount    private boolean mIsHidden;
668cab50afda0d8485436f72a93d668697f549d3b3George Mount
67c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private Bundle mExitSharedElementBundle;
68c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
69700db2a325bced35cebc403f272f988fad522892George Mount    private boolean mIsExitStarted;
70700db2a325bced35cebc403f272f988fad522892George Mount
71b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount    private boolean mSharedElementsHidden;
72b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount
7362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public ExitTransitionCoordinator(Activity activity, ArrayList<String> names,
741fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount            ArrayList<String> accepted, ArrayList<View> mapped, boolean isReturning) {
75fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        super(activity.getWindow(), names, getListener(activity, isReturning), isReturning);
761fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount        viewsReady(mapSharedElements(accepted, mapped));
7760625b02ac099bacc96a387ec270751745dafae0George Mount        stripOffscreenViews();
78a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        mIsBackgroundReady = !isReturning;
7962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        mActivity = activity;
8031a217290cf376d0573fc36e21c8940987485019George Mount    }
8131a217290cf376d0573fc36e21c8940987485019George Mount
826558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount    private static SharedElementCallback getListener(Activity activity, boolean isReturning) {
83d80154fba1c23834b5139aa764f9426bbf38a721George Mount        return isReturning ? activity.mEnterTransitionListener : activity.mExitTransitionListener;
84800d72b0e05049e4a8f90ea96ec165fc975264ceGeorge Mount    }
85800d72b0e05049e4a8f90ea96ec165fc975264ceGeorge Mount
8631a217290cf376d0573fc36e21c8940987485019George Mount    @Override
8762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected void onReceiveResult(int resultCode, Bundle resultData) {
8862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        switch (resultCode) {
8962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            case MSG_SET_REMOTE_RECEIVER:
90fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                stopCancel();
9162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mResultReceiver = resultData.getParcelable(KEY_REMOTE_RECEIVER);
9262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                if (mIsCanceled) {
9362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                    mResultReceiver.send(MSG_CANCEL, null);
9462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                    mResultReceiver = null;
9562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                } else {
9662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                    notifyComplete();
9762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
9862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                break;
9962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            case MSG_HIDE_SHARED_ELEMENTS:
100fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                stopCancel();
10162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                if (!mIsCanceled) {
10262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                    hideSharedElements();
10362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
10462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                break;
10562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            case MSG_START_EXIT_TRANSITION:
106fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                mHandler.removeMessages(MSG_CANCEL);
10762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                startExit();
10862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                break;
109c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            case MSG_SHARED_ELEMENT_DESTINATION:
110c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                mExitSharedElementBundle = resultData;
11167d924341a1d0994ac68b3b7898d5576edd987b4George Mount                sharedElementExitBack();
11267d924341a1d0994ac68b3b7898d5576edd987b4George Mount                break;
11367d924341a1d0994ac68b3b7898d5576edd987b4George Mount        }
11467d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
11567d924341a1d0994ac68b3b7898d5576edd987b4George Mount
116fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    private void stopCancel() {
117fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        if (mHandler != null) {
118fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            mHandler.removeMessages(MSG_CANCEL);
119fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
120fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
121fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
122fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    private void delayCancel() {
123fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        if (mHandler != null) {
124fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            mHandler.sendEmptyMessageDelayed(MSG_CANCEL, MAX_WAIT_MS);
125fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        }
126fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
127fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
1281fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount    public void resetViews() {
129b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount        setTransitionAlpha(mTransitioningViews, 1);
130b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount        setTransitionAlpha(mSharedElements, 1);
1311fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount        mIsHidden = true;
13209d9c3be8ab46cb2919af0eadb9851186575834aDake Gu        if (!mIsReturning && getDecor() != null) {
133f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu            getDecor().suppressLayout(false);
134f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu        }
135fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        moveSharedElementsFromOverlay();
1368d3cd2c8cf8ec355265941a8457ffd8e2e348648George Mount        clearState();
1371fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount    }
1381fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount
13967d924341a1d0994ac68b3b7898d5576edd987b4George Mount    private void sharedElementExitBack() {
140f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu        if (getDecor() != null) {
141f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu            getDecor().suppressLayout(true);
142f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu        }
143872efe45d5b3a4d6376cd15e118d5bb68ef334daDake Gu        if (mExitSharedElementBundle != null && !mExitSharedElementBundle.isEmpty() &&
144872efe45d5b3a4d6376cd15e118d5bb68ef334daDake Gu                !mSharedElements.isEmpty() && getSharedElementTransition() != null) {
14567d924341a1d0994ac68b3b7898d5576edd987b4George Mount            startTransition(new Runnable() {
14667d924341a1d0994ac68b3b7898d5576edd987b4George Mount                public void run() {
147c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                    startSharedElementExit();
148c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                }
14967d924341a1d0994ac68b3b7898d5576edd987b4George Mount            });
15000dde0bd469ba7a34369dcaaa701bd06fdf6c3adGeorge Mount        } else {
15100dde0bd469ba7a34369dcaaa701bd06fdf6c3adGeorge Mount            sharedElementTransitionComplete();
152c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
153c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
154c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
155c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private void startSharedElementExit() {
15667d924341a1d0994ac68b3b7898d5576edd987b4George Mount        Transition transition = getSharedElementExitTransition();
157fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        transition.addListener(new Transition.TransitionListenerAdapter() {
158fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            @Override
159fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            public void onTransitionEnd(Transition transition) {
160fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                transition.removeListener(this);
161fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                if (mExitComplete) {
162fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                    delayCancel();
163fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                }
164fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            }
165fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        });
16667d924341a1d0994ac68b3b7898d5576edd987b4George Mount        final ArrayList<View> sharedElementSnapshots = createSnapshots(mExitSharedElementBundle,
16767d924341a1d0994ac68b3b7898d5576edd987b4George Mount                mSharedElementNames);
16867d924341a1d0994ac68b3b7898d5576edd987b4George Mount        getDecor().getViewTreeObserver()
16967d924341a1d0994ac68b3b7898d5576edd987b4George Mount                .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
17067d924341a1d0994ac68b3b7898d5576edd987b4George Mount                    @Override
17167d924341a1d0994ac68b3b7898d5576edd987b4George Mount                    public boolean onPreDraw() {
17267d924341a1d0994ac68b3b7898d5576edd987b4George Mount                        getDecor().getViewTreeObserver().removeOnPreDrawListener(this);
17367d924341a1d0994ac68b3b7898d5576edd987b4George Mount                        setSharedElementState(mExitSharedElementBundle, sharedElementSnapshots);
17467d924341a1d0994ac68b3b7898d5576edd987b4George Mount                        return true;
17567d924341a1d0994ac68b3b7898d5576edd987b4George Mount                    }
17667d924341a1d0994ac68b3b7898d5576edd987b4George Mount                });
177fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        setGhostVisibility(View.INVISIBLE);
178fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        scheduleGhostVisibilityChange(View.INVISIBLE);
1796558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount        mListener.onSharedElementEnd(mSharedElementNames, mSharedElements, sharedElementSnapshots);
18067d924341a1d0994ac68b3b7898d5576edd987b4George Mount        TransitionManager.beginDelayedTransition(getDecor(), transition);
181fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        scheduleGhostVisibilityChange(View.VISIBLE);
182fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        setGhostVisibility(View.VISIBLE);
18367d924341a1d0994ac68b3b7898d5576edd987b4George Mount        getDecor().invalidate();
18467d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
18567d924341a1d0994ac68b3b7898d5576edd987b4George Mount
18662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private void hideSharedElements() {
187fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        moveSharedElementsFromOverlay();
18867d924341a1d0994ac68b3b7898d5576edd987b4George Mount        if (!mIsHidden) {
189b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount            setTransitionAlpha(mSharedElements, 0);
19067d924341a1d0994ac68b3b7898d5576edd987b4George Mount        }
191b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount        mSharedElementsHidden = true;
192c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        finishIfNecessary();
19331a217290cf376d0573fc36e21c8940987485019George Mount    }
19431a217290cf376d0573fc36e21c8940987485019George Mount
19562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public void startExit() {
196700db2a325bced35cebc403f272f988fad522892George Mount        if (!mIsExitStarted) {
197700db2a325bced35cebc403f272f988fad522892George Mount            mIsExitStarted = true;
198f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu            if (getDecor() != null) {
199f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu                getDecor().suppressLayout(true);
200f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu            }
201fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            moveSharedElementsToOverlay();
202700db2a325bced35cebc403f272f988fad522892George Mount            startTransition(new Runnable() {
203700db2a325bced35cebc403f272f988fad522892George Mount                @Override
204700db2a325bced35cebc403f272f988fad522892George Mount                public void run() {
205700db2a325bced35cebc403f272f988fad522892George Mount                    beginTransitions();
206700db2a325bced35cebc403f272f988fad522892George Mount                }
207700db2a325bced35cebc403f272f988fad522892George Mount            });
208700db2a325bced35cebc403f272f988fad522892George Mount        }
20931a217290cf376d0573fc36e21c8940987485019George Mount    }
21031a217290cf376d0573fc36e21c8940987485019George Mount
21162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    public void startExit(int resultCode, Intent data) {
212700db2a325bced35cebc403f272f988fad522892George Mount        if (!mIsExitStarted) {
213700db2a325bced35cebc403f272f988fad522892George Mount            mIsExitStarted = true;
214f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu            if (getDecor() != null) {
215f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu                getDecor().suppressLayout(true);
216f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu            }
217700db2a325bced35cebc403f272f988fad522892George Mount            mHandler = new Handler() {
218700db2a325bced35cebc403f272f988fad522892George Mount                @Override
219700db2a325bced35cebc403f272f988fad522892George Mount                public void handleMessage(Message msg) {
220700db2a325bced35cebc403f272f988fad522892George Mount                    mIsCanceled = true;
221700db2a325bced35cebc403f272f988fad522892George Mount                    finish();
22262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
223700db2a325bced35cebc403f272f988fad522892George Mount            };
224fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            delayCancel();
225fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            moveSharedElementsToOverlay();
226700db2a325bced35cebc403f272f988fad522892George Mount            if (getDecor().getBackground() == null) {
22785b764e22babfe5508286fbad5d7fee12345704fCraig Mautner                getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
22862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            }
229700db2a325bced35cebc403f272f988fad522892George Mount            ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
230700db2a325bced35cebc403f272f988fad522892George Mount                    mAllSharedElementNames, resultCode, data);
231700db2a325bced35cebc403f272f988fad522892George Mount            mActivity.convertToTranslucent(new Activity.TranslucentConversionListener() {
232700db2a325bced35cebc403f272f988fad522892George Mount                @Override
233700db2a325bced35cebc403f272f988fad522892George Mount                public void onTranslucentConversionComplete(boolean drawComplete) {
234700db2a325bced35cebc403f272f988fad522892George Mount                    if (!mIsCanceled) {
235700db2a325bced35cebc403f272f988fad522892George Mount                        fadeOutBackground();
236700db2a325bced35cebc403f272f988fad522892George Mount                    }
237700db2a325bced35cebc403f272f988fad522892George Mount                }
238700db2a325bced35cebc403f272f988fad522892George Mount            }, options);
239700db2a325bced35cebc403f272f988fad522892George Mount            startTransition(new Runnable() {
240700db2a325bced35cebc403f272f988fad522892George Mount                @Override
241700db2a325bced35cebc403f272f988fad522892George Mount                public void run() {
242700db2a325bced35cebc403f272f988fad522892George Mount                    startExitTransition();
243700db2a325bced35cebc403f272f988fad522892George Mount                }
244700db2a325bced35cebc403f272f988fad522892George Mount            });
245700db2a325bced35cebc403f272f988fad522892George Mount        }
24667d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
24767d924341a1d0994ac68b3b7898d5576edd987b4George Mount
24867d924341a1d0994ac68b3b7898d5576edd987b4George Mount    private void startExitTransition() {
249f451d8a6d1a454f338e37f99c0867e17ce9e06f1George Mount        Transition transition = getExitTransition();
25067d924341a1d0994ac68b3b7898d5576edd987b4George Mount        if (transition != null) {
251c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            TransitionManager.beginDelayedTransition(getDecor(), transition);
252b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount            mTransitioningViews.get(0).invalidate();
253b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount        } else {
254b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount            transitionStarted();
255c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
25631a217290cf376d0573fc36e21c8940987485019George Mount    }
25731a217290cf376d0573fc36e21c8940987485019George Mount
25862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private void fadeOutBackground() {
2598cab50afda0d8485436f72a93d668697f549d3b3George Mount        if (mBackgroundAnimator == null) {
260700db2a325bced35cebc403f272f988fad522892George Mount            ViewGroup decor = getDecor();
261700db2a325bced35cebc403f272f988fad522892George Mount            Drawable background;
262700db2a325bced35cebc403f272f988fad522892George Mount            if (decor != null && (background = decor.getBackground()) != null) {
26399c82fd1de23deeb8cf640bb574c76af76429df6George Mount                background = background.mutate();
26499c82fd1de23deeb8cf640bb574c76af76429df6George Mount                getWindow().setBackgroundDrawable(background);
265700db2a325bced35cebc403f272f988fad522892George Mount                mBackgroundAnimator = ObjectAnimator.ofInt(background, "alpha", 0);
266700db2a325bced35cebc403f272f988fad522892George Mount                mBackgroundAnimator.addListener(new AnimatorListenerAdapter() {
267700db2a325bced35cebc403f272f988fad522892George Mount                    @Override
268700db2a325bced35cebc403f272f988fad522892George Mount                    public void onAnimationEnd(Animator animation) {
269700db2a325bced35cebc403f272f988fad522892George Mount                        mBackgroundAnimator = null;
270700db2a325bced35cebc403f272f988fad522892George Mount                        if (!mIsCanceled) {
271700db2a325bced35cebc403f272f988fad522892George Mount                            mIsBackgroundReady = true;
272700db2a325bced35cebc403f272f988fad522892George Mount                            notifyComplete();
273700db2a325bced35cebc403f272f988fad522892George Mount                        }
2748cab50afda0d8485436f72a93d668697f549d3b3George Mount                    }
275700db2a325bced35cebc403f272f988fad522892George Mount                });
276700db2a325bced35cebc403f272f988fad522892George Mount                mBackgroundAnimator.setDuration(getFadeDuration());
277700db2a325bced35cebc403f272f988fad522892George Mount                mBackgroundAnimator.start();
278b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount            } else {
279b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount                mIsBackgroundReady = true;
280700db2a325bced35cebc403f272f988fad522892George Mount            }
2818cab50afda0d8485436f72a93d668697f549d3b3George Mount        }
28231a217290cf376d0573fc36e21c8940987485019George Mount    }
28331a217290cf376d0573fc36e21c8940987485019George Mount
284c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private Transition getExitTransition() {
285c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Transition viewsTransition = null;
286c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (!mTransitioningViews.isEmpty()) {
2878881502da5b319e139ab85c1825d2d2d239356a1George Mount            viewsTransition = configureTransition(getViewsTransition(), true);
288c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
289c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (viewsTransition == null) {
290c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            exitTransitionComplete();
29162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        } else {
29267d924341a1d0994ac68b3b7898d5576edd987b4George Mount            viewsTransition.addListener(new ContinueTransitionListener() {
29362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                @Override
29462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                public void onTransitionEnd(Transition transition) {
295a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount                    transition.removeListener(this);
296c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                    exitTransitionComplete();
297c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                    if (mIsHidden) {
298b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount                        setTransitionAlpha(mTransitioningViews, 1);
299c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                    }
300fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                    if (mSharedElementBundle != null) {
301fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                        delayCancel();
302fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                    }
303fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                    super.onTransitionEnd(transition);
30462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
30562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            });
306b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount            viewsTransition.forceVisibility(View.INVISIBLE, false);
30762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        }
308c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        return viewsTransition;
309c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
310c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
311c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private Transition getSharedElementExitTransition() {
312c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Transition sharedElementTransition = null;
313c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (!mSharedElements.isEmpty()) {
3148881502da5b319e139ab85c1825d2d2d239356a1George Mount            sharedElementTransition = configureTransition(getSharedElementTransition(), false);
315c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
316c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (sharedElementTransition == null) {
317c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            sharedElementTransitionComplete();
31862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        } else {
31967d924341a1d0994ac68b3b7898d5576edd987b4George Mount            sharedElementTransition.addListener(new ContinueTransitionListener() {
32062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                @Override
32162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                public void onTransitionEnd(Transition transition) {
322a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount                    transition.removeListener(this);
323c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                    sharedElementTransitionComplete();
3248cab50afda0d8485436f72a93d668697f549d3b3George Mount                    if (mIsHidden) {
325b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount                        setTransitionAlpha(mSharedElements, 1);
3268cab50afda0d8485436f72a93d668697f549d3b3George Mount                    }
32762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                }
32862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            });
329c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            mSharedElements.get(0).invalidate();
33062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        }
331c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        return sharedElementTransition;
332c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
333c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
334c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private void beginTransitions() {
335c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Transition sharedElementTransition = getSharedElementExitTransition();
336c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        Transition viewsTransition = getExitTransition();
33762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
33862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        Transition transition = mergeTransitions(sharedElementTransition, viewsTransition);
339c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (transition != null) {
340fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            setGhostVisibility(View.INVISIBLE);
341fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            scheduleGhostVisibilityChange(View.INVISIBLE);
342c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            TransitionManager.beginDelayedTransition(getDecor(), transition);
343fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            scheduleGhostVisibilityChange(View.VISIBLE);
344fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount            setGhostVisibility(View.VISIBLE);
345b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount            getDecor().invalidate();
346b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount        } else {
347b4c5d7bf218865d28f030c852fd303e127d676dbGeorge Mount            transitionStarted();
348a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        }
34962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    }
35062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount
35162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private void exitTransitionComplete() {
35231a217290cf376d0573fc36e21c8940987485019George Mount        mExitComplete = true;
35362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        notifyComplete();
35431a217290cf376d0573fc36e21c8940987485019George Mount    }
35531a217290cf376d0573fc36e21c8940987485019George Mount
35662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected boolean isReadyToNotify() {
35767d924341a1d0994ac68b3b7898d5576edd987b4George Mount        return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady;
35831a217290cf376d0573fc36e21c8940987485019George Mount    }
35931a217290cf376d0573fc36e21c8940987485019George Mount
36062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    private void sharedElementTransitionComplete() {
36167d924341a1d0994ac68b3b7898d5576edd987b4George Mount        mSharedElementBundle = mExitSharedElementBundle == null
36267d924341a1d0994ac68b3b7898d5576edd987b4George Mount                ? captureSharedElementState() : captureExitSharedElementsState();
36362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        notifyComplete();
36431a217290cf376d0573fc36e21c8940987485019George Mount    }
36531a217290cf376d0573fc36e21c8940987485019George Mount
36667d924341a1d0994ac68b3b7898d5576edd987b4George Mount    private Bundle captureExitSharedElementsState() {
36767d924341a1d0994ac68b3b7898d5576edd987b4George Mount        Bundle bundle = new Bundle();
3687bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        RectF bounds = new RectF();
3697bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu        Matrix matrix = new Matrix();
37001e9a97fe68dbba42a0edd0ad965ccfe2b8efe7dGeorge Mount        for (int i = 0; i < mSharedElements.size(); i++) {
37167d924341a1d0994ac68b3b7898d5576edd987b4George Mount            String name = mSharedElementNames.get(i);
37267d924341a1d0994ac68b3b7898d5576edd987b4George Mount            Bundle sharedElementState = mExitSharedElementBundle.getBundle(name);
37367d924341a1d0994ac68b3b7898d5576edd987b4George Mount            if (sharedElementState != null) {
37467d924341a1d0994ac68b3b7898d5576edd987b4George Mount                bundle.putBundle(name, sharedElementState);
37567d924341a1d0994ac68b3b7898d5576edd987b4George Mount            } else {
37667d924341a1d0994ac68b3b7898d5576edd987b4George Mount                View view = mSharedElements.get(i);
3777bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu                captureSharedElementState(view, name, bundle, matrix, bounds);
37867d924341a1d0994ac68b3b7898d5576edd987b4George Mount            }
37967d924341a1d0994ac68b3b7898d5576edd987b4George Mount        }
38067d924341a1d0994ac68b3b7898d5576edd987b4George Mount        return bundle;
38167d924341a1d0994ac68b3b7898d5576edd987b4George Mount    }
38267d924341a1d0994ac68b3b7898d5576edd987b4George Mount
38362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount    protected void notifyComplete() {
38462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount        if (isReadyToNotify()) {
38562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            if (!mSharedElementNotified) {
38662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mSharedElementNotified = true;
387fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount                delayCancel();
38862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mResultReceiver.send(MSG_TAKE_SHARED_ELEMENTS, mSharedElementBundle);
38962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            }
39062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            if (!mExitNotified && mExitComplete) {
39162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mExitNotified = true;
39262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mResultReceiver.send(MSG_EXIT_TRANSITION_COMPLETE, null);
39362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount                mResultReceiver = null; // done talking
39409d9c3be8ab46cb2919af0eadb9851186575834aDake Gu                if (!mIsReturning && getDecor() != null) {
395f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu                    getDecor().suppressLayout(false);
396f7ff2205d96e468950e9011de60d2ff4bd84c66dDake Gu                }
397c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount                finishIfNecessary();
39862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount            }
39931a217290cf376d0573fc36e21c8940987485019George Mount        }
40031a217290cf376d0573fc36e21c8940987485019George Mount    }
40131a217290cf376d0573fc36e21c8940987485019George Mount
402c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    private void finishIfNecessary() {
403e678ab686643127b4b297ae7a1e4869b4cfc6e53George Mount        if (mIsReturning && mExitNotified && mActivity != null && (mSharedElements.isEmpty() ||
404b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount                mSharedElementsHidden)) {
405a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount            finish();
406c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
407c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        if (!mIsReturning && mExitNotified) {
408c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount            mActivity = null; // don't need it anymore
409c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount        }
410c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount    }
411c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount
412a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount    private void finish() {
413fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        stopCancel();
414a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mActivity.mActivityTransitionState.clear();
415a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        // Clear the state so that we can't hold any references accidentally and leak memory.
416a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mHandler.removeMessages(MSG_CANCEL);
417a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mHandler = null;
418a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mActivity.finish();
419a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mActivity.overridePendingTransition(0, 0);
420a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mActivity = null;
421a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mSharedElementBundle = null;
422a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        if (mBackgroundAnimator != null) {
423a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount            mBackgroundAnimator.cancel();
424a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount            mBackgroundAnimator = null;
425a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        }
426a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        mExitSharedElementBundle = null;
427a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount        clearState();
428a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount    }
429a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount
430a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    @Override
431fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    protected boolean moveSharedElementWithParent() {
432fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount        return !mIsReturning;
433fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    }
434fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount
435fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount    @Override
436a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    protected Transition getViewsTransition() {
437a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        if (mIsReturning) {
43868f96d8db5e5e701b6a12b5cddecc985e56a26c6George Mount            return getWindow().getReturnTransition();
439a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        } else {
440a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount            return getWindow().getExitTransition();
441a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        }
442a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    }
443a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount
444a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    protected Transition getSharedElementTransition() {
445a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        if (mIsReturning) {
44668f96d8db5e5e701b6a12b5cddecc985e56a26c6George Mount            return getWindow().getSharedElementReturnTransition();
447a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        } else {
448a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount            return getWindow().getSharedElementExitTransition();
449a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount        }
450a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount    }
45131a217290cf376d0573fc36e21c8940987485019George Mount}
452