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 18c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.content.Context; 19c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.graphics.Matrix; 2031a217290cf376d0573fc36e21c8940987485019George Mountimport android.graphics.Rect; 217bf379c8af399626d5b8b568fe1d4f96f56badccDake Guimport android.graphics.RectF; 22c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.os.Bundle; 2331a217290cf376d0573fc36e21c8940987485019George Mountimport android.os.Handler; 24480ca829e2d3313740b4d14d30afbea6c98ff965George Mountimport android.os.Parcelable; 2531a217290cf376d0573fc36e21c8940987485019George Mountimport android.os.ResultReceiver; 2631a217290cf376d0573fc36e21c8940987485019George Mountimport android.transition.Transition; 2731a217290cf376d0573fc36e21c8940987485019George Mountimport android.transition.TransitionSet; 2831a217290cf376d0573fc36e21c8940987485019George Mountimport android.util.ArrayMap; 29fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mountimport android.view.GhostView; 3031a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.View; 3131a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.ViewGroup; 32fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mountimport android.view.ViewGroupOverlay; 33fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mountimport android.view.ViewParent; 34c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.view.ViewTreeObserver; 3531a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.Window; 36caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mountimport android.widget.ImageView; 3731a217290cf376d0573fc36e21c8940987485019George Mount 3831a217290cf376d0573fc36e21c8940987485019George Mountimport java.util.ArrayList; 3931a217290cf376d0573fc36e21c8940987485019George Mountimport java.util.Collection; 4031a217290cf376d0573fc36e21c8940987485019George Mount 4131a217290cf376d0573fc36e21c8940987485019George Mount/** 4231a217290cf376d0573fc36e21c8940987485019George Mount * Base class for ExitTransitionCoordinator and EnterTransitionCoordinator, classes 4331a217290cf376d0573fc36e21c8940987485019George Mount * that manage activity transitions and the communications coordinating them between 4431a217290cf376d0573fc36e21c8940987485019George Mount * Activities. The ExitTransitionCoordinator is created in the 4531a217290cf376d0573fc36e21c8940987485019George Mount * ActivityOptions#makeSceneTransitionAnimation. The EnterTransitionCoordinator 4631a217290cf376d0573fc36e21c8940987485019George Mount * is created by ActivityOptions#createEnterActivityTransition by Activity when the window is 4731a217290cf376d0573fc36e21c8940987485019George Mount * attached. 4831a217290cf376d0573fc36e21c8940987485019George Mount * 4931a217290cf376d0573fc36e21c8940987485019George Mount * Typical startActivity goes like this: 5031a217290cf376d0573fc36e21c8940987485019George Mount * 1) ExitTransitionCoordinator created with ActivityOptions#makeSceneTransitionAnimation 5131a217290cf376d0573fc36e21c8940987485019George Mount * 2) Activity#startActivity called and that calls startExit() through 5231a217290cf376d0573fc36e21c8940987485019George Mount * ActivityOptions#dispatchStartExit 5331a217290cf376d0573fc36e21c8940987485019George Mount * - Exit transition starts by setting transitioning Views to INVISIBLE 5431a217290cf376d0573fc36e21c8940987485019George Mount * 3) Launched Activity starts, creating an EnterTransitionCoordinator. 5531a217290cf376d0573fc36e21c8940987485019George Mount * - The Window is made translucent 5631a217290cf376d0573fc36e21c8940987485019George Mount * - The Window background alpha is set to 0 5731a217290cf376d0573fc36e21c8940987485019George Mount * - The transitioning views are made INVISIBLE 5831a217290cf376d0573fc36e21c8940987485019George Mount * - MSG_SET_LISTENER is sent back to the ExitTransitionCoordinator. 5931a217290cf376d0573fc36e21c8940987485019George Mount * 4) The shared element transition completes. 6031a217290cf376d0573fc36e21c8940987485019George Mount * - MSG_TAKE_SHARED_ELEMENTS is sent to the EnterTransitionCoordinator 6131a217290cf376d0573fc36e21c8940987485019George Mount * 5) The MSG_TAKE_SHARED_ELEMENTS is received by the EnterTransitionCoordinator. 6231a217290cf376d0573fc36e21c8940987485019George Mount * - Shared elements are made VISIBLE 6331a217290cf376d0573fc36e21c8940987485019George Mount * - Shared elements positions and size are set to match the end state of the calling 6431a217290cf376d0573fc36e21c8940987485019George Mount * Activity. 6531a217290cf376d0573fc36e21c8940987485019George Mount * - The shared element transition is started 6631a217290cf376d0573fc36e21c8940987485019George Mount * - If the window allows overlapping transitions, the views transition is started by setting 6731a217290cf376d0573fc36e21c8940987485019George Mount * the entering Views to VISIBLE and the background alpha is animated to opaque. 6831a217290cf376d0573fc36e21c8940987485019George Mount * - MSG_HIDE_SHARED_ELEMENTS is sent to the ExitTransitionCoordinator 6931a217290cf376d0573fc36e21c8940987485019George Mount * 6) MSG_HIDE_SHARED_ELEMENTS is received by the ExitTransitionCoordinator 7031a217290cf376d0573fc36e21c8940987485019George Mount * - The shared elements are made INVISIBLE 7131a217290cf376d0573fc36e21c8940987485019George Mount * 7) The exit transition completes in the calling Activity. 7231a217290cf376d0573fc36e21c8940987485019George Mount * - MSG_EXIT_TRANSITION_COMPLETE is sent to the EnterTransitionCoordinator. 7331a217290cf376d0573fc36e21c8940987485019George Mount * 8) The MSG_EXIT_TRANSITION_COMPLETE is received by the EnterTransitionCoordinator. 7431a217290cf376d0573fc36e21c8940987485019George Mount * - If the window doesn't allow overlapping enter transitions, the enter transition is started 7531a217290cf376d0573fc36e21c8940987485019George Mount * by setting entering views to VISIBLE and the background is animated to opaque. 7631a217290cf376d0573fc36e21c8940987485019George Mount * 9) The background opacity animation completes. 7731a217290cf376d0573fc36e21c8940987485019George Mount * - The window is made opaque 7831a217290cf376d0573fc36e21c8940987485019George Mount * 10) The calling Activity gets an onStop() call 7931a217290cf376d0573fc36e21c8940987485019George Mount * - onActivityStopped() is called and all exited Views are made VISIBLE. 8031a217290cf376d0573fc36e21c8940987485019George Mount * 8173f843de4b65772c624ca8ebb8c976a279e37ce9Craig Mautner * Typical finishAfterTransition goes like this: 8273f843de4b65772c624ca8ebb8c976a279e37ce9Craig Mautner * 1) finishAfterTransition() creates an ExitTransitionCoordinator and calls startExit() 8362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * - The Window start transitioning to Translucent with a new ActivityOptions. 8431a217290cf376d0573fc36e21c8940987485019George Mount * - If no background exists, a black background is substituted 8531a217290cf376d0573fc36e21c8940987485019George Mount * - The shared elements in the scene are matched against those shared elements 8631a217290cf376d0573fc36e21c8940987485019George Mount * that were sent by comparing the names. 8731a217290cf376d0573fc36e21c8940987485019George Mount * - The exit transition is started by setting Views to INVISIBLE. 8862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * 2) The ActivityOptions is received by the Activity and an EnterTransitionCoordinator is created. 8931a217290cf376d0573fc36e21c8940987485019George Mount * - All transitioning views are made VISIBLE to reverse what was done when onActivityStopped() 9031a217290cf376d0573fc36e21c8940987485019George Mount * was called 9131a217290cf376d0573fc36e21c8940987485019George Mount * 3) The Window is made translucent and a callback is received 9231a217290cf376d0573fc36e21c8940987485019George Mount * - The background alpha is animated to 0 9331a217290cf376d0573fc36e21c8940987485019George Mount * 4) The background alpha animation completes 9431a217290cf376d0573fc36e21c8940987485019George Mount * 5) The shared element transition completes 9531a217290cf376d0573fc36e21c8940987485019George Mount * - After both 4 & 5 complete, MSG_TAKE_SHARED_ELEMENTS is sent to the 9662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * EnterTransitionCoordinator 9762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * 6) MSG_TAKE_SHARED_ELEMENTS is received by EnterTransitionCoordinator 9831a217290cf376d0573fc36e21c8940987485019George Mount * - Shared elements are made VISIBLE 9931a217290cf376d0573fc36e21c8940987485019George Mount * - Shared elements positions and size are set to match the end state of the calling 10031a217290cf376d0573fc36e21c8940987485019George Mount * Activity. 10131a217290cf376d0573fc36e21c8940987485019George Mount * - The shared element transition is started 10231a217290cf376d0573fc36e21c8940987485019George Mount * - If the window allows overlapping transitions, the views transition is started by setting 10331a217290cf376d0573fc36e21c8940987485019George Mount * the entering Views to VISIBLE. 10462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * - MSG_HIDE_SHARED_ELEMENTS is sent to the ExitTransitionCoordinator 10562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * 7) MSG_HIDE_SHARED_ELEMENTS is received by the ExitTransitionCoordinator 10631a217290cf376d0573fc36e21c8940987485019George Mount * - The shared elements are made INVISIBLE 10731a217290cf376d0573fc36e21c8940987485019George Mount * 8) The exit transition completes in the finishing Activity. 10862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * - MSG_EXIT_TRANSITION_COMPLETE is sent to the EnterTransitionCoordinator. 10931a217290cf376d0573fc36e21c8940987485019George Mount * - finish() is called on the exiting Activity 11062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * 9) The MSG_EXIT_TRANSITION_COMPLETE is received by the EnterTransitionCoordinator. 11131a217290cf376d0573fc36e21c8940987485019George Mount * - If the window doesn't allow overlapping enter transitions, the enter transition is started 11231a217290cf376d0573fc36e21c8940987485019George Mount * by setting entering views to VISIBLE. 11331a217290cf376d0573fc36e21c8940987485019George Mount */ 11431a217290cf376d0573fc36e21c8940987485019George Mountabstract class ActivityTransitionCoordinator extends ResultReceiver { 11531a217290cf376d0573fc36e21c8940987485019George Mount private static final String TAG = "ActivityTransitionCoordinator"; 11631a217290cf376d0573fc36e21c8940987485019George Mount 11731a217290cf376d0573fc36e21c8940987485019George Mount /** 11831a217290cf376d0573fc36e21c8940987485019George Mount * For Activity transitions, the called Activity's listener to receive calls 11931a217290cf376d0573fc36e21c8940987485019George Mount * when transitions complete. 12031a217290cf376d0573fc36e21c8940987485019George Mount */ 12162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount static final String KEY_REMOTE_RECEIVER = "android:remoteReceiver"; 12262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount 1237bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu protected static final String KEY_SCREEN_LEFT = "shared_element:screenLeft"; 1247bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu protected static final String KEY_SCREEN_TOP = "shared_element:screenTop"; 1257bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu protected static final String KEY_SCREEN_RIGHT = "shared_element:screenRight"; 1267bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu protected static final String KEY_SCREEN_BOTTOM= "shared_element:screenBottom"; 12762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final String KEY_TRANSLATION_Z = "shared_element:translationZ"; 128480ca829e2d3313740b4d14d30afbea6c98ff965George Mount protected static final String KEY_SNAPSHOT = "shared_element:bitmap"; 12962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final String KEY_SCALE_TYPE = "shared_element:scaleType"; 13062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final String KEY_IMAGE_MATRIX = "shared_element:imageMatrix"; 13126c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount protected static final String KEY_ELEVATION = "shared_element:elevation"; 13231a217290cf376d0573fc36e21c8940987485019George Mount 13362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final ImageView.ScaleType[] SCALE_TYPE_VALUES = ImageView.ScaleType.values(); 13431a217290cf376d0573fc36e21c8940987485019George Mount 13531a217290cf376d0573fc36e21c8940987485019George Mount /** 13631a217290cf376d0573fc36e21c8940987485019George Mount * Sent by the exiting coordinator (either EnterTransitionCoordinator 13731a217290cf376d0573fc36e21c8940987485019George Mount * or ExitTransitionCoordinator) after the shared elements have 13831a217290cf376d0573fc36e21c8940987485019George Mount * become stationary (shared element transition completes). This tells 13931a217290cf376d0573fc36e21c8940987485019George Mount * the remote coordinator to take control of the shared elements and 14031a217290cf376d0573fc36e21c8940987485019George Mount * that animations may begin. The remote Activity won't start entering 14131a217290cf376d0573fc36e21c8940987485019George Mount * until this message is received, but may wait for 14231a217290cf376d0573fc36e21c8940987485019George Mount * MSG_EXIT_TRANSITION_COMPLETE if allowOverlappingTransitions() is true. 14331a217290cf376d0573fc36e21c8940987485019George Mount */ 14462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_SET_REMOTE_RECEIVER = 100; 14531a217290cf376d0573fc36e21c8940987485019George Mount 14631a217290cf376d0573fc36e21c8940987485019George Mount /** 14731a217290cf376d0573fc36e21c8940987485019George Mount * Sent by the entering coordinator to tell the exiting coordinator 14831a217290cf376d0573fc36e21c8940987485019George Mount * to hide its shared elements after it has started its shared 14931a217290cf376d0573fc36e21c8940987485019George Mount * element transition. This is temporary until the 15031a217290cf376d0573fc36e21c8940987485019George Mount * interlock of shared elements is figured out. 15131a217290cf376d0573fc36e21c8940987485019George Mount */ 15231a217290cf376d0573fc36e21c8940987485019George Mount public static final int MSG_HIDE_SHARED_ELEMENTS = 101; 15331a217290cf376d0573fc36e21c8940987485019George Mount 15431a217290cf376d0573fc36e21c8940987485019George Mount /** 15531a217290cf376d0573fc36e21c8940987485019George Mount * Sent by the exiting coordinator (either EnterTransitionCoordinator 15631a217290cf376d0573fc36e21c8940987485019George Mount * or ExitTransitionCoordinator) after the shared elements have 15731a217290cf376d0573fc36e21c8940987485019George Mount * become stationary (shared element transition completes). This tells 15831a217290cf376d0573fc36e21c8940987485019George Mount * the remote coordinator to take control of the shared elements and 15931a217290cf376d0573fc36e21c8940987485019George Mount * that animations may begin. The remote Activity won't start entering 16031a217290cf376d0573fc36e21c8940987485019George Mount * until this message is received, but may wait for 16131a217290cf376d0573fc36e21c8940987485019George Mount * MSG_EXIT_TRANSITION_COMPLETE if allowOverlappingTransitions() is true. 16231a217290cf376d0573fc36e21c8940987485019George Mount */ 16362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_TAKE_SHARED_ELEMENTS = 103; 16431a217290cf376d0573fc36e21c8940987485019George Mount 16531a217290cf376d0573fc36e21c8940987485019George Mount /** 16631a217290cf376d0573fc36e21c8940987485019George Mount * Sent by the exiting coordinator (either 16731a217290cf376d0573fc36e21c8940987485019George Mount * EnterTransitionCoordinator or ExitTransitionCoordinator) after 16831a217290cf376d0573fc36e21c8940987485019George Mount * the exiting Views have finished leaving the scene. This will 16931a217290cf376d0573fc36e21c8940987485019George Mount * be ignored if allowOverlappingTransitions() is true on the 17031a217290cf376d0573fc36e21c8940987485019George Mount * remote coordinator. If it is false, it will trigger the enter 17131a217290cf376d0573fc36e21c8940987485019George Mount * transition to start. 17231a217290cf376d0573fc36e21c8940987485019George Mount */ 17362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_EXIT_TRANSITION_COMPLETE = 104; 17431a217290cf376d0573fc36e21c8940987485019George Mount 17531a217290cf376d0573fc36e21c8940987485019George Mount /** 17631a217290cf376d0573fc36e21c8940987485019George Mount * Sent by Activity#startActivity to begin the exit transition. 17731a217290cf376d0573fc36e21c8940987485019George Mount */ 17862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_START_EXIT_TRANSITION = 105; 17931a217290cf376d0573fc36e21c8940987485019George Mount 18031a217290cf376d0573fc36e21c8940987485019George Mount /** 18162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * It took too long for a message from the entering Activity, so we canceled the transition. 18231a217290cf376d0573fc36e21c8940987485019George Mount */ 18362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_CANCEL = 106; 18462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount 185c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount /** 186c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * When returning, this is the destination location for the shared element. 187c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount */ 188c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount public static final int MSG_SHARED_ELEMENT_DESTINATION = 107; 189c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 190d265bd7446e662c9597226c596e8f91eda824982George Mount /** 191d265bd7446e662c9597226c596e8f91eda824982George Mount * Send the shared element positions. 192d265bd7446e662c9597226c596e8f91eda824982George Mount */ 193d265bd7446e662c9597226c596e8f91eda824982George Mount public static final int MSG_SEND_SHARED_ELEMENT_DESTINATION = 108; 194d265bd7446e662c9597226c596e8f91eda824982George Mount 195a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount private Window mWindow; 19662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final protected ArrayList<String> mAllSharedElementNames; 19762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final protected ArrayList<View> mSharedElements = new ArrayList<View>(); 19862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final protected ArrayList<String> mSharedElementNames = new ArrayList<String>(); 199b694e080546316a27d22eba759027f6cb0a24705George Mount protected ArrayList<View> mTransitioningViews = new ArrayList<View>(); 2006558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount protected SharedElementCallback mListener; 20162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected ResultReceiver mResultReceiver; 20262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final private FixedEpicenterCallback mEpicenterCallback = new FixedEpicenterCallback(); 203c9b6df8fa4df3968b2420a52c5281b4765478f68George Mount final protected boolean mIsReturning; 20467d924341a1d0994ac68b3b7898d5576edd987b4George Mount private Runnable mPendingTransition; 20567d924341a1d0994ac68b3b7898d5576edd987b4George Mount private boolean mIsStartingTransition; 206fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount private ArrayList<GhostViewListeners> mGhostViewListeners = 207fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount new ArrayList<GhostViewListeners>(); 2080f0c473488f8e8becc8883d3cdd9610324610dc4George Mount private ArrayMap<View, Float> mOriginalAlphas = new ArrayMap<View, Float>(); 209333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount final private ArrayList<View> mRootSharedElements = new ArrayList<View>(); 210333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount private ArrayList<Matrix> mSharedElementParentMatrices; 21167d924341a1d0994ac68b3b7898d5576edd987b4George Mount 2128c2614ce4328640642d8e8be437859e0508a39b4George Mount public ActivityTransitionCoordinator(Window window, 2138c2614ce4328640642d8e8be437859e0508a39b4George Mount ArrayList<String> allSharedElementNames, 2146558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount SharedElementCallback listener, boolean isReturning) { 21562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount super(new Handler()); 21662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mWindow = window; 21762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mListener = listener; 21862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mAllSharedElementNames = allSharedElementNames; 219c9b6df8fa4df3968b2420a52c5281b4765478f68George Mount mIsReturning = isReturning; 2208c2614ce4328640642d8e8be437859e0508a39b4George Mount } 2218c2614ce4328640642d8e8be437859e0508a39b4George Mount 2221fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount protected void viewsReady(ArrayMap<String, View> sharedElements) { 223ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount sharedElements.retainAll(mAllSharedElementNames); 2241732f528952ea2df0bfd503fabb958af03dbfc81George Mount if (mListener != null) { 2251732f528952ea2df0bfd503fabb958af03dbfc81George Mount mListener.onMapSharedElements(mAllSharedElementNames, sharedElements); 2261732f528952ea2df0bfd503fabb958af03dbfc81George Mount } 227333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount setSharedElements(sharedElements); 228b694e080546316a27d22eba759027f6cb0a24705George Mount if (getViewsTransition() != null && mTransitioningViews != null) { 22948bd13c9cb2627847cf1f7707a084eb354e9c303George Mount ViewGroup decorView = getDecor(); 23048bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (decorView != null) { 23148bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.captureTransitioningViews(mTransitioningViews); 23248bd13c9cb2627847cf1f7707a084eb354e9c303George Mount } 23362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mTransitioningViews.removeAll(mSharedElements); 23431a217290cf376d0573fc36e21c8940987485019George Mount } 23562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount setEpicenter(); 23631a217290cf376d0573fc36e21c8940987485019George Mount } 23731a217290cf376d0573fc36e21c8940987485019George Mount 238333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount /** 239333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount * Iterates over the shared elements and adds them to the members in order. 240333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount * Shared elements that are nested in other shared elements are placed after the 241333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount * elements that they are nested in. This means that layout ordering can be done 242333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount * from first to last. 243333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount * 244333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount * @param sharedElements The map of transition names to shared elements to set into 245333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount * the member fields. 246333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount */ 247333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount private void setSharedElements(ArrayMap<String, View> sharedElements) { 248333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount boolean isFirstRun = true; 249333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount while (!sharedElements.isEmpty()) { 250333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount final int numSharedElements = sharedElements.size(); 251333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount for (int i = numSharedElements - 1; i >= 0; i--) { 252333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount final View view = sharedElements.valueAt(i); 253333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount final String name = sharedElements.keyAt(i); 254333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount if (isFirstRun && (view == null || !view.isAttachedToWindow() || name == null)) { 255333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount sharedElements.removeAt(i); 256333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } else { 257333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount if (!isNested(view, sharedElements)) { 258333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount mSharedElementNames.add(name); 259333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount mSharedElements.add(view); 260333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount sharedElements.removeAt(i); 261333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount if (isFirstRun) { 262333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount // We need to keep track which shared elements are roots 263333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount // and which are nested. 264333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount mRootSharedElements.add(view); 265333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 266333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 267333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 268333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 269333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount isFirstRun = false; 270333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 271333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 272333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount 273333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount /** 274333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount * Returns true when view is nested in any of the values of sharedElements. 275333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount */ 276333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount private static boolean isNested(View view, ArrayMap<String, View> sharedElements) { 277333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount ViewParent parent = view.getParent(); 278333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount boolean isNested = false; 279333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount while (parent instanceof View) { 280333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount View parentView = (View) parent; 281333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount if (sharedElements.containsValue(parentView)) { 282333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount isNested = true; 283333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount break; 284333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 285333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount parent = parentView.getParent(); 286333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 287333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount return isNested; 288333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 289333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount 29060625b02ac099bacc96a387ec270751745dafae0George Mount protected void stripOffscreenViews() { 291b694e080546316a27d22eba759027f6cb0a24705George Mount if (mTransitioningViews == null) { 292b694e080546316a27d22eba759027f6cb0a24705George Mount return; 293b694e080546316a27d22eba759027f6cb0a24705George Mount } 29460625b02ac099bacc96a387ec270751745dafae0George Mount Rect r = new Rect(); 29560625b02ac099bacc96a387ec270751745dafae0George Mount for (int i = mTransitioningViews.size() - 1; i >= 0; i--) { 29660625b02ac099bacc96a387ec270751745dafae0George Mount View view = mTransitioningViews.get(i); 29760625b02ac099bacc96a387ec270751745dafae0George Mount if (!view.getGlobalVisibleRect(r)) { 29860625b02ac099bacc96a387ec270751745dafae0George Mount mTransitioningViews.remove(i); 299653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount showView(view, true); 30060625b02ac099bacc96a387ec270751745dafae0George Mount } 30160625b02ac099bacc96a387ec270751745dafae0George Mount } 30260625b02ac099bacc96a387ec270751745dafae0George Mount } 30360625b02ac099bacc96a387ec270751745dafae0George Mount 30431a217290cf376d0573fc36e21c8940987485019George Mount protected Window getWindow() { 30531a217290cf376d0573fc36e21c8940987485019George Mount return mWindow; 30631a217290cf376d0573fc36e21c8940987485019George Mount } 30731a217290cf376d0573fc36e21c8940987485019George Mount 308a2bbbb3bac464c3a52e33008401fed4a7542744cGeorge Mount public ViewGroup getDecor() { 30931a217290cf376d0573fc36e21c8940987485019George Mount return (mWindow == null) ? null : (ViewGroup) mWindow.getDecorView(); 31031a217290cf376d0573fc36e21c8940987485019George Mount } 31131a217290cf376d0573fc36e21c8940987485019George Mount 31262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount /** 31362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * Sets the transition epicenter to the position of the first shared element. 31462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount */ 31562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected void setEpicenter() { 31662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount View epicenter = null; 317c6186bffe477b996e388046e8761908b813fd07fGeorge Mount if (!mAllSharedElementNames.isEmpty() && !mSharedElementNames.isEmpty()) { 318c6186bffe477b996e388046e8761908b813fd07fGeorge Mount int index = mSharedElementNames.indexOf(mAllSharedElementNames.get(0)); 319c6186bffe477b996e388046e8761908b813fd07fGeorge Mount if (index >= 0) { 320c6186bffe477b996e388046e8761908b813fd07fGeorge Mount epicenter = mSharedElements.get(index); 321c6186bffe477b996e388046e8761908b813fd07fGeorge Mount } 32231a217290cf376d0573fc36e21c8940987485019George Mount } 32362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount setEpicenter(epicenter); 32431a217290cf376d0573fc36e21c8940987485019George Mount } 32531a217290cf376d0573fc36e21c8940987485019George Mount 32662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount private void setEpicenter(View view) { 32762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (view == null) { 32862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mEpicenterCallback.setEpicenter(null); 32931a217290cf376d0573fc36e21c8940987485019George Mount } else { 3308e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount Rect epicenter = new Rect(); 3318e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount view.getBoundsOnScreen(epicenter); 33262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mEpicenterCallback.setEpicenter(epicenter); 33331a217290cf376d0573fc36e21c8940987485019George Mount } 33431a217290cf376d0573fc36e21c8940987485019George Mount } 33531a217290cf376d0573fc36e21c8940987485019George Mount 33662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public ArrayList<String> getAcceptedNames() { 33762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return mSharedElementNames; 33831a217290cf376d0573fc36e21c8940987485019George Mount } 33931a217290cf376d0573fc36e21c8940987485019George Mount 34062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public ArrayList<String> getMappedNames() { 34162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount ArrayList<String> names = new ArrayList<String>(mSharedElements.size()); 34262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount for (int i = 0; i < mSharedElements.size(); i++) { 3430a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount names.add(mSharedElements.get(i).getTransitionName()); 344080443bcb63418245c2408500db735fece5e7083George Mount } 34562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return names; 34631a217290cf376d0573fc36e21c8940987485019George Mount } 34731a217290cf376d0573fc36e21c8940987485019George Mount 348700db2a325bced35cebc403f272f988fad522892George Mount public ArrayList<View> copyMappedViews() { 349700db2a325bced35cebc403f272f988fad522892George Mount return new ArrayList<View>(mSharedElements); 3501fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount } 3511fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount 3528c2614ce4328640642d8e8be437859e0508a39b4George Mount public ArrayList<String> getAllSharedElementNames() { return mAllSharedElementNames; } 3538c2614ce4328640642d8e8be437859e0508a39b4George Mount 3548881502da5b319e139ab85c1825d2d2d239356a1George Mount protected Transition setTargets(Transition transition, boolean add) { 3558881502da5b319e139ab85c1825d2d2d239356a1George Mount if (transition == null || (add && 3568881502da5b319e139ab85c1825d2d2d239356a1George Mount (mTransitioningViews == null || mTransitioningViews.isEmpty()))) { 35731a217290cf376d0573fc36e21c8940987485019George Mount return null; 35831a217290cf376d0573fc36e21c8940987485019George Mount } 359d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // Add the targets to a set containing transition so that transition 360d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // remains unaffected. We don't want to modify the targets of transition itself. 36131a217290cf376d0573fc36e21c8940987485019George Mount TransitionSet set = new TransitionSet(); 3628881502da5b319e139ab85c1825d2d2d239356a1George Mount if (mTransitioningViews != null) { 3638881502da5b319e139ab85c1825d2d2d239356a1George Mount for (int i = mTransitioningViews.size() - 1; i >= 0; i--) { 3648881502da5b319e139ab85c1825d2d2d239356a1George Mount View view = mTransitioningViews.get(i); 3658881502da5b319e139ab85c1825d2d2d239356a1George Mount if (add) { 3668881502da5b319e139ab85c1825d2d2d239356a1George Mount set.addTarget(view); 3678881502da5b319e139ab85c1825d2d2d239356a1George Mount } else { 3688881502da5b319e139ab85c1825d2d2d239356a1George Mount set.excludeTarget(view, true); 3698881502da5b319e139ab85c1825d2d2d239356a1George Mount } 37031a217290cf376d0573fc36e21c8940987485019George Mount } 37131a217290cf376d0573fc36e21c8940987485019George Mount } 372d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // By adding the transition after addTarget, we prevent addTarget from 373d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // affecting transition. 374d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount set.addTransition(transition); 375fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 376fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (!add && mTransitioningViews != null && !mTransitioningViews.isEmpty()) { 377fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount // Allow children of excluded transitioning views, but not the views themselves 378fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount set = new TransitionSet().addTransition(set); 379fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 380fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 38131a217290cf376d0573fc36e21c8940987485019George Mount return set; 38231a217290cf376d0573fc36e21c8940987485019George Mount } 38331a217290cf376d0573fc36e21c8940987485019George Mount 3848881502da5b319e139ab85c1825d2d2d239356a1George Mount protected Transition configureTransition(Transition transition, 3858881502da5b319e139ab85c1825d2d2d239356a1George Mount boolean includeTransitioningViews) { 38631a217290cf376d0573fc36e21c8940987485019George Mount if (transition != null) { 38762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount transition = transition.clone(); 38862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount transition.setEpicenterCallback(mEpicenterCallback); 3898881502da5b319e139ab85c1825d2d2d239356a1George Mount transition = setTargets(transition, includeTransitioningViews); 39031a217290cf376d0573fc36e21c8940987485019George Mount } 39131a217290cf376d0573fc36e21c8940987485019George Mount return transition; 39231a217290cf376d0573fc36e21c8940987485019George Mount } 39331a217290cf376d0573fc36e21c8940987485019George Mount 39462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static Transition mergeTransitions(Transition transition1, Transition transition2) { 39562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (transition1 == null) { 39662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return transition2; 39762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } else if (transition2 == null) { 39862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return transition1; 39962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } else { 40062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount TransitionSet transitionSet = new TransitionSet(); 40162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount transitionSet.addTransition(transition1); 40262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount transitionSet.addTransition(transition2); 40362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return transitionSet; 40462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 40562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 40662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount 4071fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount protected ArrayMap<String, View> mapSharedElements(ArrayList<String> accepted, 4081fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount ArrayList<View> localViews) { 4091fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount ArrayMap<String, View> sharedElements = new ArrayMap<String, View>(); 410ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount if (accepted != null) { 411ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount for (int i = 0; i < accepted.size(); i++) { 412ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount sharedElements.put(accepted.get(i), localViews.get(i)); 413caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mount } 414ce725a47f6eee75a6ef86397e9b9fe471aeb1f84George Mount } else { 41548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount ViewGroup decorView = getDecor(); 41648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (decorView != null) { 41748bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.findNamedViews(sharedElements); 41848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount } 4191fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount } 4201fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount return sharedElements; 4211fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount } 4221fecfb2ddcdf4335ff543bdd549b8e4d36139da8George Mount 42362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected void setResultReceiver(ResultReceiver resultReceiver) { 42462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mResultReceiver = resultReceiver; 425080443bcb63418245c2408500db735fece5e7083George Mount } 426080443bcb63418245c2408500db735fece5e7083George Mount 427a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount protected abstract Transition getViewsTransition(); 428080443bcb63418245c2408500db735fece5e7083George Mount 429fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount private void setSharedElementState(View view, String name, Bundle transitionArgs, 4307bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu Matrix tempMatrix, RectF tempRect, int[] decorLoc) { 431c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle sharedElementBundle = transitionArgs.getBundle(name); 432c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (sharedElementBundle == null) { 433c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return; 434c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 435c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 436c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (view instanceof ImageView) { 437c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int scaleTypeInt = sharedElementBundle.getInt(KEY_SCALE_TYPE, -1); 438c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (scaleTypeInt >= 0) { 439c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView imageView = (ImageView) view; 440c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView.ScaleType scaleType = SCALE_TYPE_VALUES[scaleTypeInt]; 441c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount imageView.setScaleType(scaleType); 442c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (scaleType == ImageView.ScaleType.MATRIX) { 443c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount float[] matrixValues = sharedElementBundle.getFloatArray(KEY_IMAGE_MATRIX); 4447bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu tempMatrix.setValues(matrixValues); 4457bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu imageView.setImageMatrix(tempMatrix); 446c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 447c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 448c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 449c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 450c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount float z = sharedElementBundle.getFloat(KEY_TRANSLATION_Z); 451c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount view.setTranslationZ(z); 45226c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount float elevation = sharedElementBundle.getFloat(KEY_ELEVATION); 45326c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount view.setElevation(elevation); 454c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 4557bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu float left = sharedElementBundle.getFloat(KEY_SCREEN_LEFT); 4567bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu float top = sharedElementBundle.getFloat(KEY_SCREEN_TOP); 4577bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu float right = sharedElementBundle.getFloat(KEY_SCREEN_RIGHT); 4587bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu float bottom = sharedElementBundle.getFloat(KEY_SCREEN_BOTTOM); 459c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 4607bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu if (decorLoc != null) { 4617bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu left -= decorLoc[0]; 4627bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu top -= decorLoc[1]; 463480ca829e2d3313740b4d14d30afbea6c98ff965George Mount right -= decorLoc[0]; 464480ca829e2d3313740b4d14d30afbea6c98ff965George Mount bottom -= decorLoc[1]; 4657bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu } else { 4667bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu // Find the location in the view's parent 467fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount getSharedElementParentMatrix(view, tempMatrix); 4687bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu tempRect.set(left, top, right, bottom); 4697bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu tempMatrix.mapRect(tempRect); 4707bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu 4717bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu float leftInParent = tempRect.left; 4727bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu float topInParent = tempRect.top; 4737bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu 4747bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu // Find the size of the view 4757bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu view.getInverseMatrix().mapRect(tempRect); 4767bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu float width = tempRect.width(); 4777bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu float height = tempRect.height(); 4787bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu 4797bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu // Now determine the offset due to view transform: 4807bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu view.setLeft(0); 4817bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu view.setTop(0); 4827bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu view.setRight(Math.round(width)); 4837bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu view.setBottom(Math.round(height)); 4847bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu tempRect.set(0, 0, width, height); 4857bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu view.getMatrix().mapRect(tempRect); 4867bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu 487fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount ViewGroup parent = (ViewGroup) view.getParent(); 4887bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu left = leftInParent - tempRect.left + parent.getScrollX(); 4897bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu top = topInParent - tempRect.top + parent.getScrollY(); 4907bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu right = left + width; 4917bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu bottom = top + height; 4927bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu } 4937bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu 4947bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu int x = Math.round(left); 4957bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu int y = Math.round(top); 4967bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu int width = Math.round(right) - x; 4977bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu int height = Math.round(bottom) - y; 498c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); 499c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY); 500c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount view.measure(widthSpec, heightSpec); 501c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 5027bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu view.layout(x, y, x + width, y + height); 503c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 504c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 505333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount private void setSharedElementMatrices() { 506333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount int numSharedElements = mSharedElements.size(); 507333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount if (numSharedElements > 0) { 508333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount mSharedElementParentMatrices = new ArrayList<Matrix>(numSharedElements); 509333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 510333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount for (int i = 0; i < numSharedElements; i++) { 511333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount View view = mSharedElements.get(i); 512333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount 513333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount // Find the location in the view's parent 514333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount ViewGroup parent = (ViewGroup) view.getParent(); 515333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount Matrix matrix = new Matrix(); 516333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount parent.transformMatrixToLocal(matrix); 517333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount 518333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount mSharedElementParentMatrices.add(matrix); 519333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 520333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 521333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount 522333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount private void getSharedElementParentMatrix(View view, Matrix matrix) { 523333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount final boolean isNestedInOtherSharedElement = !mRootSharedElements.contains(view); 524333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount final boolean useParentMatrix; 525333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount if (isNestedInOtherSharedElement) { 526333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount useParentMatrix = true; 527333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } else { 528333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount final int index = mSharedElementParentMatrices == null ? -1 529333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount : mSharedElements.indexOf(view); 530333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount if (index < 0) { 531333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount useParentMatrix = true; 532333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } else { 533333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount // The indices of mSharedElementParentMatrices matches the 534333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount // mSharedElement matrices. 535333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount Matrix parentMatrix = mSharedElementParentMatrices.get(index); 536333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount matrix.set(parentMatrix); 537333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount useParentMatrix = false; 538333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 539333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 540333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount if (useParentMatrix) { 541333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount matrix.reset(); 542333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount ViewParent viewParent = view.getParent(); 543333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount if (viewParent instanceof ViewGroup) { 544333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount // Find the location in the view's parent 545333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount ViewGroup parent = (ViewGroup) viewParent; 546333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount parent.transformMatrixToLocal(matrix); 547333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 548333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount } 549fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 550fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 551c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu protected ArrayList<SharedElementOriginalState> setSharedElementState( 552c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle sharedElementState, final ArrayList<View> snapshots) { 553c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu ArrayList<SharedElementOriginalState> originalImageState = 554c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu new ArrayList<SharedElementOriginalState>(); 555c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (sharedElementState != null) { 5567bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu Matrix tempMatrix = new Matrix(); 5577bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu RectF tempRect = new RectF(); 5581732f528952ea2df0bfd503fabb958af03dbfc81George Mount final int numSharedElements = mSharedElements.size(); 5591732f528952ea2df0bfd503fabb958af03dbfc81George Mount for (int i = 0; i < numSharedElements; i++) { 560c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount View sharedElement = mSharedElements.get(i); 561c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount String name = mSharedElementNames.get(i); 562c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu SharedElementOriginalState originalState = getOldSharedElementState(sharedElement, 563c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount name, sharedElementState); 564c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu originalImageState.add(originalState); 5657bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu setSharedElementState(sharedElement, name, sharedElementState, 5667bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu tempMatrix, tempRect, null); 567c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 568c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 5691732f528952ea2df0bfd503fabb958af03dbfc81George Mount if (mListener != null) { 5701732f528952ea2df0bfd503fabb958af03dbfc81George Mount mListener.onSharedElementStart(mSharedElementNames, mSharedElements, snapshots); 5711732f528952ea2df0bfd503fabb958af03dbfc81George Mount } 572fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount return originalImageState; 573fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 574fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 575fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount protected void notifySharedElementEnd(ArrayList<View> snapshots) { 5761732f528952ea2df0bfd503fabb958af03dbfc81George Mount if (mListener != null) { 5771732f528952ea2df0bfd503fabb958af03dbfc81George Mount mListener.onSharedElementEnd(mSharedElementNames, mSharedElements, snapshots); 5781732f528952ea2df0bfd503fabb958af03dbfc81George Mount } 579fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 580c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 581fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount protected void scheduleSetSharedElementEnd(final ArrayList<View> snapshots) { 5826e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount final View decorView = getDecor(); 58348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (decorView != null) { 58448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.getViewTreeObserver().addOnPreDrawListener( 58548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount new ViewTreeObserver.OnPreDrawListener() { 58648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount @Override 58748bd13c9cb2627847cf1f7707a084eb354e9c303George Mount public boolean onPreDraw() { 58848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.getViewTreeObserver().removeOnPreDrawListener(this); 58948bd13c9cb2627847cf1f7707a084eb354e9c303George Mount notifySharedElementEnd(snapshots); 59048bd13c9cb2627847cf1f7707a084eb354e9c303George Mount return true; 59148bd13c9cb2627847cf1f7707a084eb354e9c303George Mount } 592c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 59348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount ); 59448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount } 595c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 596c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 597c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu private static SharedElementOriginalState getOldSharedElementState(View view, String name, 598c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle transitionArgs) { 599c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu 600c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu SharedElementOriginalState state = new SharedElementOriginalState(); 601c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu state.mLeft = view.getLeft(); 602c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu state.mTop = view.getTop(); 603c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu state.mRight = view.getRight(); 604c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu state.mBottom = view.getBottom(); 605c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu state.mMeasuredWidth = view.getMeasuredWidth(); 606c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu state.mMeasuredHeight = view.getMeasuredHeight(); 60726c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount state.mTranslationZ = view.getTranslationZ(); 60826c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount state.mElevation = view.getElevation(); 609c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (!(view instanceof ImageView)) { 610c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu return state; 611c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 612c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle bundle = transitionArgs.getBundle(name); 613c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (bundle == null) { 614c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu return state; 615c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 616c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int scaleTypeInt = bundle.getInt(KEY_SCALE_TYPE, -1); 617c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (scaleTypeInt < 0) { 618c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu return state; 619c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 620c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 621c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView imageView = (ImageView) view; 622c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu state.mScaleType = imageView.getScaleType(); 623c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu if (state.mScaleType == ImageView.ScaleType.MATRIX) { 624c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu state.mMatrix = new Matrix(imageView.getImageMatrix()); 625c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 626c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu return state; 627c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 628c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 629c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount protected ArrayList<View> createSnapshots(Bundle state, Collection<String> names) { 630c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int numSharedElements = names.size(); 6317c479f5a013fb5544be45cd3a952190fc3a923fcGeorge Mount ArrayList<View> snapshots = new ArrayList<View>(numSharedElements); 632c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (numSharedElements == 0) { 6337c479f5a013fb5544be45cd3a952190fc3a923fcGeorge Mount return snapshots; 634c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 635c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Context context = getWindow().getContext(); 6367bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu int[] decorLoc = new int[2]; 63748bd13c9cb2627847cf1f7707a084eb354e9c303George Mount ViewGroup decorView = getDecor(); 63848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (decorView != null) { 63948bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.getLocationOnScreen(decorLoc); 64048bd13c9cb2627847cf1f7707a084eb354e9c303George Mount } 641ca5094a05ce177c586f873ad556e7afc2656fe12George Mount Matrix tempMatrix = new Matrix(); 642c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount for (String name: names) { 643c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle sharedElementBundle = state.getBundle(name); 64492692c0284c2249e9a5381f7f19ec97f6b76d12fGeorge Mount View snapshot = null; 645c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (sharedElementBundle != null) { 646480ca829e2d3313740b4d14d30afbea6c98ff965George Mount Parcelable parcelable = sharedElementBundle.getParcelable(KEY_SNAPSHOT); 6471732f528952ea2df0bfd503fabb958af03dbfc81George Mount if (parcelable != null && mListener != null) { 6486558056e8fccc32f9e1dc59e46d09f8d916b7538George Mount snapshot = mListener.onCreateSnapshotView(context, parcelable); 649480ca829e2d3313740b4d14d30afbea6c98ff965George Mount } 650480ca829e2d3313740b4d14d30afbea6c98ff965George Mount if (snapshot != null) { 651ca5094a05ce177c586f873ad556e7afc2656fe12George Mount setSharedElementState(snapshot, name, state, tempMatrix, null, decorLoc); 652c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 653c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 65492692c0284c2249e9a5381f7f19ec97f6b76d12fGeorge Mount // Even null snapshots are added so they remain in the same order as shared elements. 65592692c0284c2249e9a5381f7f19ec97f6b76d12fGeorge Mount snapshots.add(snapshot); 656c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 657c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return snapshots; 658c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 659c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 660c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu protected static void setOriginalSharedElementState(ArrayList<View> sharedElements, 661c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu ArrayList<SharedElementOriginalState> originalState) { 662c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount for (int i = 0; i < originalState.size(); i++) { 663c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu View view = sharedElements.get(i); 664c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu SharedElementOriginalState state = originalState.get(i); 665c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu if (view instanceof ImageView && state.mScaleType != null) { 666c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu ImageView imageView = (ImageView) view; 667c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu imageView.setScaleType(state.mScaleType); 668c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu if (state.mScaleType == ImageView.ScaleType.MATRIX) { 669c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu imageView.setImageMatrix(state.mMatrix); 670c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu } 671c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu } 67226c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount view.setElevation(state.mElevation); 67326c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount view.setTranslationZ(state.mTranslationZ); 67426c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount int widthSpec = View.MeasureSpec.makeMeasureSpec(state.mMeasuredWidth, 675c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu View.MeasureSpec.EXACTLY); 676c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu int heightSpec = View.MeasureSpec.makeMeasureSpec(state.mMeasuredHeight, 677c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu View.MeasureSpec.EXACTLY); 678c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu view.measure(widthSpec, heightSpec); 679c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu view.layout(state.mLeft, state.mTop, state.mRight, state.mBottom); 680c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 681c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 682c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 683c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount protected Bundle captureSharedElementState() { 684c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle bundle = new Bundle(); 6857bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu RectF tempBounds = new RectF(); 6867bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu Matrix tempMatrix = new Matrix(); 687f03c139018dd5b6f1ea53ac902caec7b6ee9ddd3Dake Gu for (int i = 0; i < mSharedElements.size(); i++) { 688c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount View sharedElement = mSharedElements.get(i); 689c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount String name = mSharedElementNames.get(i); 6907bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu captureSharedElementState(sharedElement, name, bundle, tempMatrix, tempBounds); 691c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 692c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return bundle; 693c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 694c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 695a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount protected void clearState() { 696a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount // Clear the state so that we can't hold any references accidentally and leak memory. 697a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount mWindow = null; 698a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount mSharedElements.clear(); 699b694e080546316a27d22eba759027f6cb0a24705George Mount mTransitioningViews = null; 7000f0c473488f8e8becc8883d3cdd9610324610dc4George Mount mOriginalAlphas.clear(); 701a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount mResultReceiver = null; 702a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount mPendingTransition = null; 703fc0fc0e341f2a2d707d5a8eafd65db34bdffb35cDake Gu mListener = null; 704333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount mRootSharedElements.clear(); 705333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount mSharedElementParentMatrices = null; 706a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount } 707a0a0260e48e1ee4e9b5d98b49571e8d2a6fd6c3aGeorge Mount 708ed1e01d7e431edbcaab983b4b240418f2b090facGeorge Mount protected long getFadeDuration() { 709ed1e01d7e431edbcaab983b4b240418f2b090facGeorge Mount return getWindow().getTransitionBackgroundFadeDuration(); 710ed1e01d7e431edbcaab983b4b240418f2b090facGeorge Mount } 711ed1e01d7e431edbcaab983b4b240418f2b090facGeorge Mount 7120f0c473488f8e8becc8883d3cdd9610324610dc4George Mount protected void hideViews(ArrayList<View> views) { 713fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount int count = views.size(); 714fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount for (int i = 0; i < count; i++) { 7150f0c473488f8e8becc8883d3cdd9610324610dc4George Mount View view = views.get(i); 7160f0c473488f8e8becc8883d3cdd9610324610dc4George Mount if (!mOriginalAlphas.containsKey(view)) { 7170f0c473488f8e8becc8883d3cdd9610324610dc4George Mount mOriginalAlphas.put(view, view.getAlpha()); 7180f0c473488f8e8becc8883d3cdd9610324610dc4George Mount } 7190f0c473488f8e8becc8883d3cdd9610324610dc4George Mount view.setAlpha(0f); 7200f0c473488f8e8becc8883d3cdd9610324610dc4George Mount } 7210f0c473488f8e8becc8883d3cdd9610324610dc4George Mount } 7220f0c473488f8e8becc8883d3cdd9610324610dc4George Mount 723ce2ee3d6de670e52abed7f432778701113ba9c07George Mount protected void showViews(ArrayList<View> views, boolean setTransitionAlpha) { 7240f0c473488f8e8becc8883d3cdd9610324610dc4George Mount int count = views.size(); 7250f0c473488f8e8becc8883d3cdd9610324610dc4George Mount for (int i = 0; i < count; i++) { 726653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount showView(views.get(i), setTransitionAlpha); 727653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount } 728653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount } 729653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount 730653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount private void showView(View view, boolean setTransitionAlpha) { 731653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount Float alpha = mOriginalAlphas.remove(view); 732653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount if (alpha != null) { 733653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount view.setAlpha(alpha); 734653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount } 735653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount if (setTransitionAlpha) { 736653ea66a9f609deec4b4370550396c47a85d713cGeorge Mount view.setTransitionAlpha(1f); 737b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } 738b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount } 739b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount 740c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount /** 741c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * Captures placement information for Views with a shared element name for 742c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * Activity Transitions. 743c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * 744c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * @param view The View to capture the placement information for. 745c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * @param name The shared element name in the target Activity to apply the placement 746c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * information for. 747c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * @param transitionArgs Bundle to store shared element placement information. 7488e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount * @param tempBounds A temporary Rect for capturing the current location of views. 749c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount */ 750480ca829e2d3313740b4d14d30afbea6c98ff965George Mount protected void captureSharedElementState(View view, String name, Bundle transitionArgs, 7517bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu Matrix tempMatrix, RectF tempBounds) { 752c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle sharedElementBundle = new Bundle(); 7537bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu tempMatrix.reset(); 7547bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu view.transformMatrixToGlobal(tempMatrix); 7558e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount tempBounds.set(0, 0, view.getWidth(), view.getHeight()); 7567bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu tempMatrix.mapRect(tempBounds); 757c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 7587bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu sharedElementBundle.putFloat(KEY_SCREEN_LEFT, tempBounds.left); 7597bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu sharedElementBundle.putFloat(KEY_SCREEN_RIGHT, tempBounds.right); 7607bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu sharedElementBundle.putFloat(KEY_SCREEN_TOP, tempBounds.top); 7617bf379c8af399626d5b8b568fe1d4f96f56badccDake Gu sharedElementBundle.putFloat(KEY_SCREEN_BOTTOM, tempBounds.bottom); 762c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ()); 76326c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount sharedElementBundle.putFloat(KEY_ELEVATION, view.getElevation()); 764c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 7651732f528952ea2df0bfd503fabb958af03dbfc81George Mount Parcelable bitmap = null; 7661732f528952ea2df0bfd503fabb958af03dbfc81George Mount if (mListener != null) { 7671732f528952ea2df0bfd503fabb958af03dbfc81George Mount bitmap = mListener.onCaptureSharedElementSnapshot(view, tempMatrix, tempBounds); 7681732f528952ea2df0bfd503fabb958af03dbfc81George Mount } 7691732f528952ea2df0bfd503fabb958af03dbfc81George Mount 770480ca829e2d3313740b4d14d30afbea6c98ff965George Mount if (bitmap != null) { 771480ca829e2d3313740b4d14d30afbea6c98ff965George Mount sharedElementBundle.putParcelable(KEY_SNAPSHOT, bitmap); 772c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 773c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 774c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (view instanceof ImageView) { 775c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView imageView = (ImageView) view; 776c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int scaleTypeInt = scaleTypeToInt(imageView.getScaleType()); 777c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementBundle.putInt(KEY_SCALE_TYPE, scaleTypeInt); 778c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (imageView.getScaleType() == ImageView.ScaleType.MATRIX) { 779c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount float[] matrix = new float[9]; 780c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount imageView.getImageMatrix().getValues(matrix); 781c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementBundle.putFloatArray(KEY_IMAGE_MATRIX, matrix); 782c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 783c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 784c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 785c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount transitionArgs.putBundle(name, sharedElementBundle); 786c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 787c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 78867d924341a1d0994ac68b3b7898d5576edd987b4George Mount 78967d924341a1d0994ac68b3b7898d5576edd987b4George Mount protected void startTransition(Runnable runnable) { 79067d924341a1d0994ac68b3b7898d5576edd987b4George Mount if (mIsStartingTransition) { 79167d924341a1d0994ac68b3b7898d5576edd987b4George Mount mPendingTransition = runnable; 79267d924341a1d0994ac68b3b7898d5576edd987b4George Mount } else { 79367d924341a1d0994ac68b3b7898d5576edd987b4George Mount mIsStartingTransition = true; 79467d924341a1d0994ac68b3b7898d5576edd987b4George Mount runnable.run(); 79567d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 79667d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 79767d924341a1d0994ac68b3b7898d5576edd987b4George Mount 79813ccb79b34f6db1580714ea980c8490121d7e5aeGeorge Mount protected void transitionStarted() { 79913ccb79b34f6db1580714ea980c8490121d7e5aeGeorge Mount mIsStartingTransition = false; 80013ccb79b34f6db1580714ea980c8490121d7e5aeGeorge Mount } 80113ccb79b34f6db1580714ea980c8490121d7e5aeGeorge Mount 802fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount /** 803fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount * Cancels any pending transitions and returns true if there is a transition is in 804fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount * the middle of starting. 805fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount */ 806fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount protected boolean cancelPendingTransitions() { 807fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount mPendingTransition = null; 808fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount return mIsStartingTransition; 809fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount } 810fbd459642fe732115f135e456eafdec2dc8e9bb6George Mount 811fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount protected void moveSharedElementsToOverlay() { 812eca1ae5e442bf5f13617ab823343730619512632George Mount if (mWindow == null || !mWindow.getSharedElementsUseOverlay()) { 813b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount return; 814b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount } 815333b8093eaab4b55d91a7a0b3b1484424f8ac975George Mount setSharedElementMatrices(); 816fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount int numSharedElements = mSharedElements.size(); 817fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount ViewGroup decor = getDecor(); 818fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (decor != null) { 819fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount boolean moveWithParent = moveSharedElementWithParent(); 820fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount for (int i = 0; i < numSharedElements; i++) { 821fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount View view = mSharedElements.get(i); 822fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount GhostView.addGhost(view, decor); 823fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount ViewGroup parent = (ViewGroup) view.getParent(); 824fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (moveWithParent && !isInTransitionGroup(parent, decor)) { 8256e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount GhostViewListeners listener = new GhostViewListeners(view, parent, decor); 826fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount parent.getViewTreeObserver().addOnPreDrawListener(listener); 827fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount mGhostViewListeners.add(listener); 828fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 829fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 830fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 831fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 832fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 833fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount protected boolean moveSharedElementWithParent() { 834fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount return true; 835fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 836fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 837fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount public static boolean isInTransitionGroup(ViewParent viewParent, ViewGroup decor) { 838fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (viewParent == decor || !(viewParent instanceof ViewGroup)) { 839fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount return false; 840fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 841fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount ViewGroup parent = (ViewGroup) viewParent; 842fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (parent.isTransitionGroup()) { 843fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount return true; 844fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } else { 845fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount return isInTransitionGroup(parent.getParent(), decor); 846fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 847fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 848fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 849fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount protected void moveSharedElementsFromOverlay() { 850b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount int numListeners = mGhostViewListeners.size(); 851b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount for (int i = 0; i < numListeners; i++) { 852b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount GhostViewListeners listener = mGhostViewListeners.get(i); 853b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount ViewGroup parent = (ViewGroup) listener.getView().getParent(); 854b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount parent.getViewTreeObserver().removeOnPreDrawListener(listener); 855b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount } 856b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount mGhostViewListeners.clear(); 857b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount 858b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount if (mWindow == null || !mWindow.getSharedElementsUseOverlay()) { 859b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount return; 860b89d5cc2c64112a0ff7e66e4dd3bb2114caed935George Mount } 861fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount ViewGroup decor = getDecor(); 862fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (decor != null) { 863fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount ViewGroupOverlay overlay = decor.getOverlay(); 864fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount int count = mSharedElements.size(); 865fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount for (int i = 0; i < count; i++) { 866fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount View sharedElement = mSharedElements.get(i); 867fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount GhostView.removeGhost(sharedElement); 868fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 869fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 870fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 871fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 872fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount protected void setGhostVisibility(int visibility) { 873fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount int numSharedElements = mSharedElements.size(); 874fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount for (int i = 0; i < numSharedElements; i++) { 875fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount GhostView ghostView = GhostView.getGhost(mSharedElements.get(i)); 876fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (ghostView != null) { 877fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount ghostView.setVisibility(visibility); 878fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 879fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 880fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 881fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 882fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount protected void scheduleGhostVisibilityChange(final int visibility) { 8836e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount final View decorView = getDecor(); 88448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount if (decorView != null) { 88548bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.getViewTreeObserver() 88648bd13c9cb2627847cf1f7707a084eb354e9c303George Mount .addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 88748bd13c9cb2627847cf1f7707a084eb354e9c303George Mount @Override 88848bd13c9cb2627847cf1f7707a084eb354e9c303George Mount public boolean onPreDraw() { 88948bd13c9cb2627847cf1f7707a084eb354e9c303George Mount decorView.getViewTreeObserver().removeOnPreDrawListener(this); 89048bd13c9cb2627847cf1f7707a084eb354e9c303George Mount setGhostVisibility(visibility); 89148bd13c9cb2627847cf1f7707a084eb354e9c303George Mount return true; 89248bd13c9cb2627847cf1f7707a084eb354e9c303George Mount } 89348bd13c9cb2627847cf1f7707a084eb354e9c303George Mount }); 89448bd13c9cb2627847cf1f7707a084eb354e9c303George Mount } 895fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 896fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 89767d924341a1d0994ac68b3b7898d5576edd987b4George Mount protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter { 89867d924341a1d0994ac68b3b7898d5576edd987b4George Mount @Override 89967d924341a1d0994ac68b3b7898d5576edd987b4George Mount public void onTransitionStart(Transition transition) { 90067d924341a1d0994ac68b3b7898d5576edd987b4George Mount mIsStartingTransition = false; 90167d924341a1d0994ac68b3b7898d5576edd987b4George Mount Runnable pending = mPendingTransition; 90267d924341a1d0994ac68b3b7898d5576edd987b4George Mount mPendingTransition = null; 90367d924341a1d0994ac68b3b7898d5576edd987b4George Mount if (pending != null) { 90467d924341a1d0994ac68b3b7898d5576edd987b4George Mount startTransition(pending); 90567d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 90667d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 90767d924341a1d0994ac68b3b7898d5576edd987b4George Mount } 90867d924341a1d0994ac68b3b7898d5576edd987b4George Mount 909c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount private static int scaleTypeToInt(ImageView.ScaleType scaleType) { 910c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount for (int i = 0; i < SCALE_TYPE_VALUES.length; i++) { 911c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (scaleType == SCALE_TYPE_VALUES[i]) { 912c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return i; 913c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 914c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 915c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return -1; 916c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 917c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 91831a217290cf376d0573fc36e21c8940987485019George Mount private static class FixedEpicenterCallback extends Transition.EpicenterCallback { 91931a217290cf376d0573fc36e21c8940987485019George Mount private Rect mEpicenter; 92031a217290cf376d0573fc36e21c8940987485019George Mount 92131a217290cf376d0573fc36e21c8940987485019George Mount public void setEpicenter(Rect epicenter) { mEpicenter = epicenter; } 92231a217290cf376d0573fc36e21c8940987485019George Mount 92331a217290cf376d0573fc36e21c8940987485019George Mount @Override 924dc21d3b2804c24fe29ec860796d11185901364c4George Mount public Rect onGetEpicenter(Transition transition) { 92531a217290cf376d0573fc36e21c8940987485019George Mount return mEpicenter; 92631a217290cf376d0573fc36e21c8940987485019George Mount } 92731a217290cf376d0573fc36e21c8940987485019George Mount } 928800d72b0e05049e4a8f90ea96ec165fc975264ceGeorge Mount 929fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount private static class GhostViewListeners implements ViewTreeObserver.OnPreDrawListener { 930fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount private View mView; 931fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount private ViewGroup mDecor; 9326e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount private View mParent; 933fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount private Matrix mMatrix = new Matrix(); 934fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 9356e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount public GhostViewListeners(View view, View parent, ViewGroup decor) { 936fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount mView = view; 9376e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount mParent = parent; 938fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount mDecor = decor; 939fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 940fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 941fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount public View getView() { 942fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount return mView; 943fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 944fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 945fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount @Override 946fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount public boolean onPreDraw() { 947fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount GhostView ghostView = GhostView.getGhost(mView); 948fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (ghostView == null) { 9496e7fb60b93d3449d256282a9cc34ba3356add90eGeorge Mount mParent.getViewTreeObserver().removeOnPreDrawListener(this); 950fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } else { 951fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount GhostView.calculateMatrix(mView, mDecor, mMatrix); 952fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount ghostView.setMatrix(mMatrix); 953fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 954fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount return true; 955fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 956fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount } 957fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount 958c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu static class SharedElementOriginalState { 959c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu int mLeft; 960c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu int mTop; 961c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu int mRight; 962c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu int mBottom; 963c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu int mMeasuredWidth; 964c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu int mMeasuredHeight; 965c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu ImageView.ScaleType mScaleType; 966c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu Matrix mMatrix; 96726c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount float mTranslationZ; 96826c82b6ed1e8e7276fe2ca65c241fc4c4cac6d12George Mount float mElevation; 969c18f4cc0f2dfb05b22c6187c5c2c2dead4f504a5Dake Gu } 97031a217290cf376d0573fc36e21c8940987485019George Mount} 971