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