ActivityTransitionCoordinator.java revision 8c2614ce4328640642d8e8be437859e0508a39b4
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.content.res.Resources; 20c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.graphics.Bitmap; 21c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.graphics.Canvas; 22c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.graphics.Matrix; 2331a217290cf376d0573fc36e21c8940987485019George Mountimport android.graphics.Rect; 24c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.graphics.drawable.BitmapDrawable; 25c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.os.Bundle; 2631a217290cf376d0573fc36e21c8940987485019George Mountimport android.os.Handler; 2731a217290cf376d0573fc36e21c8940987485019George Mountimport android.os.ResultReceiver; 2831a217290cf376d0573fc36e21c8940987485019George Mountimport android.transition.Transition; 2931a217290cf376d0573fc36e21c8940987485019George Mountimport android.transition.TransitionSet; 3031a217290cf376d0573fc36e21c8940987485019George Mountimport android.util.ArrayMap; 31c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mountimport android.util.Pair; 3231a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.View; 3331a217290cf376d0573fc36e21c8940987485019George Mountimport android.view.ViewGroup; 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 12362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final String KEY_SCREEN_X = "shared_element:screenX"; 12462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final String KEY_SCREEN_Y = "shared_element:screenY"; 12562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final String KEY_TRANSLATION_Z = "shared_element:translationZ"; 12662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final String KEY_WIDTH = "shared_element:width"; 12762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final String KEY_HEIGHT = "shared_element:height"; 12862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final String KEY_BITMAP = "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"; 13131a217290cf376d0573fc36e21c8940987485019George Mount 132d265bd7446e662c9597226c596e8f91eda824982George Mount // The background fade in/out duration. TODO: Enable tuning this. 133d265bd7446e662c9597226c596e8f91eda824982George Mount public static final int FADE_BACKGROUND_DURATION_MS = 300; 134080443bcb63418245c2408500db735fece5e7083George Mount 13562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static final ImageView.ScaleType[] SCALE_TYPE_VALUES = ImageView.ScaleType.values(); 13631a217290cf376d0573fc36e21c8940987485019George Mount 13731a217290cf376d0573fc36e21c8940987485019George Mount /** 13831a217290cf376d0573fc36e21c8940987485019George Mount * Sent by the exiting coordinator (either EnterTransitionCoordinator 13931a217290cf376d0573fc36e21c8940987485019George Mount * or ExitTransitionCoordinator) after the shared elements have 14031a217290cf376d0573fc36e21c8940987485019George Mount * become stationary (shared element transition completes). This tells 14131a217290cf376d0573fc36e21c8940987485019George Mount * the remote coordinator to take control of the shared elements and 14231a217290cf376d0573fc36e21c8940987485019George Mount * that animations may begin. The remote Activity won't start entering 14331a217290cf376d0573fc36e21c8940987485019George Mount * until this message is received, but may wait for 14431a217290cf376d0573fc36e21c8940987485019George Mount * MSG_EXIT_TRANSITION_COMPLETE if allowOverlappingTransitions() is true. 14531a217290cf376d0573fc36e21c8940987485019George Mount */ 14662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_SET_REMOTE_RECEIVER = 100; 14731a217290cf376d0573fc36e21c8940987485019George Mount 14831a217290cf376d0573fc36e21c8940987485019George Mount /** 14931a217290cf376d0573fc36e21c8940987485019George Mount * Sent by the entering coordinator to tell the exiting coordinator 15031a217290cf376d0573fc36e21c8940987485019George Mount * to hide its shared elements after it has started its shared 15131a217290cf376d0573fc36e21c8940987485019George Mount * element transition. This is temporary until the 15231a217290cf376d0573fc36e21c8940987485019George Mount * interlock of shared elements is figured out. 15331a217290cf376d0573fc36e21c8940987485019George Mount */ 15431a217290cf376d0573fc36e21c8940987485019George Mount public static final int MSG_HIDE_SHARED_ELEMENTS = 101; 15531a217290cf376d0573fc36e21c8940987485019George Mount 15631a217290cf376d0573fc36e21c8940987485019George Mount /** 15731a217290cf376d0573fc36e21c8940987485019George Mount * Sent by the exiting Activity in ActivityOptions#dispatchActivityStopped 15831a217290cf376d0573fc36e21c8940987485019George Mount * to leave the Activity in a good state after it has been hidden. 15931a217290cf376d0573fc36e21c8940987485019George Mount */ 16062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_ACTIVITY_STOPPED = 102; 16131a217290cf376d0573fc36e21c8940987485019George Mount 16231a217290cf376d0573fc36e21c8940987485019George Mount /** 16331a217290cf376d0573fc36e21c8940987485019George Mount * Sent by the exiting coordinator (either EnterTransitionCoordinator 16431a217290cf376d0573fc36e21c8940987485019George Mount * or ExitTransitionCoordinator) after the shared elements have 16531a217290cf376d0573fc36e21c8940987485019George Mount * become stationary (shared element transition completes). This tells 16631a217290cf376d0573fc36e21c8940987485019George Mount * the remote coordinator to take control of the shared elements and 16731a217290cf376d0573fc36e21c8940987485019George Mount * that animations may begin. The remote Activity won't start entering 16831a217290cf376d0573fc36e21c8940987485019George Mount * until this message is received, but may wait for 16931a217290cf376d0573fc36e21c8940987485019George Mount * MSG_EXIT_TRANSITION_COMPLETE if allowOverlappingTransitions() is true. 17031a217290cf376d0573fc36e21c8940987485019George Mount */ 17162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_TAKE_SHARED_ELEMENTS = 103; 17231a217290cf376d0573fc36e21c8940987485019George Mount 17331a217290cf376d0573fc36e21c8940987485019George Mount /** 17431a217290cf376d0573fc36e21c8940987485019George Mount * Sent by the exiting coordinator (either 17531a217290cf376d0573fc36e21c8940987485019George Mount * EnterTransitionCoordinator or ExitTransitionCoordinator) after 17631a217290cf376d0573fc36e21c8940987485019George Mount * the exiting Views have finished leaving the scene. This will 17731a217290cf376d0573fc36e21c8940987485019George Mount * be ignored if allowOverlappingTransitions() is true on the 17831a217290cf376d0573fc36e21c8940987485019George Mount * remote coordinator. If it is false, it will trigger the enter 17931a217290cf376d0573fc36e21c8940987485019George Mount * transition to start. 18031a217290cf376d0573fc36e21c8940987485019George Mount */ 18162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_EXIT_TRANSITION_COMPLETE = 104; 18231a217290cf376d0573fc36e21c8940987485019George Mount 18331a217290cf376d0573fc36e21c8940987485019George Mount /** 18431a217290cf376d0573fc36e21c8940987485019George Mount * Sent by Activity#startActivity to begin the exit transition. 18531a217290cf376d0573fc36e21c8940987485019George Mount */ 18662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_START_EXIT_TRANSITION = 105; 18731a217290cf376d0573fc36e21c8940987485019George Mount 18831a217290cf376d0573fc36e21c8940987485019George Mount /** 18962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * It took too long for a message from the entering Activity, so we canceled the transition. 19031a217290cf376d0573fc36e21c8940987485019George Mount */ 19162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public static final int MSG_CANCEL = 106; 19262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount 193c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount /** 194c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * When returning, this is the destination location for the shared element. 195c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount */ 196c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount public static final int MSG_SHARED_ELEMENT_DESTINATION = 107; 197c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 198d265bd7446e662c9597226c596e8f91eda824982George Mount /** 199d265bd7446e662c9597226c596e8f91eda824982George Mount * Send the shared element positions. 200d265bd7446e662c9597226c596e8f91eda824982George Mount */ 201d265bd7446e662c9597226c596e8f91eda824982George Mount public static final int MSG_SEND_SHARED_ELEMENT_DESTINATION = 108; 202d265bd7446e662c9597226c596e8f91eda824982George Mount 20362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final private Window mWindow; 20462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final protected ArrayList<String> mAllSharedElementNames; 20562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final protected ArrayList<View> mSharedElements = new ArrayList<View>(); 20662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final protected ArrayList<String> mSharedElementNames = new ArrayList<String>(); 20762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final protected ArrayList<View> mTransitioningViews = new ArrayList<View>(); 20862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final protected SharedElementListener mListener; 20962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected ResultReceiver mResultReceiver; 21062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount final private FixedEpicenterCallback mEpicenterCallback = new FixedEpicenterCallback(); 211c9b6df8fa4df3968b2420a52c5281b4765478f68George Mount final protected boolean mIsReturning; 21262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount 21362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public ActivityTransitionCoordinator(Window window, 21462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount ArrayList<String> allSharedElementNames, 21562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount ArrayList<String> accepted, ArrayList<String> localNames, 216c9b6df8fa4df3968b2420a52c5281b4765478f68George Mount SharedElementListener listener, boolean isReturning) { 2178c2614ce4328640642d8e8be437859e0508a39b4George Mount this(window, allSharedElementNames, listener, isReturning); 2188c2614ce4328640642d8e8be437859e0508a39b4George Mount viewsReady(accepted, localNames); 2198c2614ce4328640642d8e8be437859e0508a39b4George Mount } 2208c2614ce4328640642d8e8be437859e0508a39b4George Mount 2218c2614ce4328640642d8e8be437859e0508a39b4George Mount public ActivityTransitionCoordinator(Window window, 2228c2614ce4328640642d8e8be437859e0508a39b4George Mount ArrayList<String> allSharedElementNames, 2238c2614ce4328640642d8e8be437859e0508a39b4George Mount SharedElementListener listener, boolean isReturning) { 22462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount super(new Handler()); 22562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mWindow = window; 22662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mListener = listener; 22762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mAllSharedElementNames = allSharedElementNames; 228c9b6df8fa4df3968b2420a52c5281b4765478f68George Mount mIsReturning = isReturning; 2298c2614ce4328640642d8e8be437859e0508a39b4George Mount } 2308c2614ce4328640642d8e8be437859e0508a39b4George Mount 2318c2614ce4328640642d8e8be437859e0508a39b4George Mount protected void viewsReady(ArrayList<String> accepted, ArrayList<String> localNames) { 23262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount setSharedElements(accepted, localNames); 23331a217290cf376d0573fc36e21c8940987485019George Mount if (getViewsTransition() != null) { 23462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount getDecor().captureTransitioningViews(mTransitioningViews); 23562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mTransitioningViews.removeAll(mSharedElements); 23631a217290cf376d0573fc36e21c8940987485019George Mount } 23762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount setEpicenter(); 23831a217290cf376d0573fc36e21c8940987485019George Mount } 23931a217290cf376d0573fc36e21c8940987485019George Mount 24031a217290cf376d0573fc36e21c8940987485019George Mount protected Window getWindow() { 24131a217290cf376d0573fc36e21c8940987485019George Mount return mWindow; 24231a217290cf376d0573fc36e21c8940987485019George Mount } 24331a217290cf376d0573fc36e21c8940987485019George Mount 24431a217290cf376d0573fc36e21c8940987485019George Mount protected ViewGroup getDecor() { 24531a217290cf376d0573fc36e21c8940987485019George Mount return (mWindow == null) ? null : (ViewGroup) mWindow.getDecorView(); 24631a217290cf376d0573fc36e21c8940987485019George Mount } 24731a217290cf376d0573fc36e21c8940987485019George Mount 24862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount /** 24962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount * Sets the transition epicenter to the position of the first shared element. 25062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount */ 25162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected void setEpicenter() { 25262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount View epicenter = null; 25362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (!mAllSharedElementNames.isEmpty() && !mSharedElementNames.isEmpty() && 25462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mAllSharedElementNames.get(0).equals(mSharedElementNames.get(0))) { 25562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount epicenter = mSharedElements.get(0); 25631a217290cf376d0573fc36e21c8940987485019George Mount } 25762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount setEpicenter(epicenter); 25831a217290cf376d0573fc36e21c8940987485019George Mount } 25931a217290cf376d0573fc36e21c8940987485019George Mount 26062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount private void setEpicenter(View view) { 26162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (view == null) { 26262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mEpicenterCallback.setEpicenter(null); 26331a217290cf376d0573fc36e21c8940987485019George Mount } else { 2648e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount Rect epicenter = new Rect(); 2658e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount view.getBoundsOnScreen(epicenter); 26662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mEpicenterCallback.setEpicenter(epicenter); 26731a217290cf376d0573fc36e21c8940987485019George Mount } 26831a217290cf376d0573fc36e21c8940987485019George Mount } 26931a217290cf376d0573fc36e21c8940987485019George Mount 27062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public ArrayList<String> getAcceptedNames() { 27162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return mSharedElementNames; 27231a217290cf376d0573fc36e21c8940987485019George Mount } 27331a217290cf376d0573fc36e21c8940987485019George Mount 27462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount public ArrayList<String> getMappedNames() { 27562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount ArrayList<String> names = new ArrayList<String>(mSharedElements.size()); 27662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount for (int i = 0; i < mSharedElements.size(); i++) { 27762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount names.add(mSharedElements.get(i).getViewName()); 278080443bcb63418245c2408500db735fece5e7083George Mount } 27962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return names; 28031a217290cf376d0573fc36e21c8940987485019George Mount } 28131a217290cf376d0573fc36e21c8940987485019George Mount 2828c2614ce4328640642d8e8be437859e0508a39b4George Mount public ArrayList<String> getAllSharedElementNames() { return mAllSharedElementNames; } 2838c2614ce4328640642d8e8be437859e0508a39b4George Mount 28431a217290cf376d0573fc36e21c8940987485019George Mount public static void setViewVisibility(Collection<View> views, int visibility) { 28531a217290cf376d0573fc36e21c8940987485019George Mount if (views != null) { 28631a217290cf376d0573fc36e21c8940987485019George Mount for (View view : views) { 28731a217290cf376d0573fc36e21c8940987485019George Mount view.setVisibility(visibility); 28831a217290cf376d0573fc36e21c8940987485019George Mount } 28931a217290cf376d0573fc36e21c8940987485019George Mount } 29031a217290cf376d0573fc36e21c8940987485019George Mount } 29131a217290cf376d0573fc36e21c8940987485019George Mount 29262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static Transition addTargets(Transition transition, Collection<View> views) { 29331a217290cf376d0573fc36e21c8940987485019George Mount if (transition == null || views == null || views.isEmpty()) { 29431a217290cf376d0573fc36e21c8940987485019George Mount return null; 29531a217290cf376d0573fc36e21c8940987485019George Mount } 29631a217290cf376d0573fc36e21c8940987485019George Mount TransitionSet set = new TransitionSet(); 29762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount set.addTransition(transition); 29831a217290cf376d0573fc36e21c8940987485019George Mount if (views != null) { 29931a217290cf376d0573fc36e21c8940987485019George Mount for (View view: views) { 30031a217290cf376d0573fc36e21c8940987485019George Mount set.addTarget(view); 30131a217290cf376d0573fc36e21c8940987485019George Mount } 30231a217290cf376d0573fc36e21c8940987485019George Mount } 30331a217290cf376d0573fc36e21c8940987485019George Mount return set; 30431a217290cf376d0573fc36e21c8940987485019George Mount } 30531a217290cf376d0573fc36e21c8940987485019George Mount 30662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected Transition configureTransition(Transition transition) { 30731a217290cf376d0573fc36e21c8940987485019George Mount if (transition != null) { 30862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount transition = transition.clone(); 30962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount transition.setEpicenterCallback(mEpicenterCallback); 31031a217290cf376d0573fc36e21c8940987485019George Mount } 31131a217290cf376d0573fc36e21c8940987485019George Mount return transition; 31231a217290cf376d0573fc36e21c8940987485019George Mount } 31331a217290cf376d0573fc36e21c8940987485019George Mount 31462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected static Transition mergeTransitions(Transition transition1, Transition transition2) { 31562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (transition1 == null) { 31662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return transition2; 31762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } else if (transition2 == null) { 31862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return transition1; 31962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } else { 32062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount TransitionSet transitionSet = new TransitionSet(); 32162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount transitionSet.addTransition(transition1); 32262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount transitionSet.addTransition(transition2); 32362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount return transitionSet; 32462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 32562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 32662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount 32762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount private void setSharedElements(ArrayList<String> accepted, ArrayList<String> localNames) { 32862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (!mAllSharedElementNames.isEmpty()) { 32962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount ArrayMap<String, View> sharedElements = new ArrayMap<String, View>(); 33062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount getDecor().findNamedViews(sharedElements); 33162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (accepted != null) { 33262ab9b78b77b7dd851c47115f4d8d7611d657585George Mount for (int i = 0; i < localNames.size(); i++) { 33362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount String localName = localNames.get(i); 33462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount String acceptedName = accepted.get(i); 33562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (!localName.equals(acceptedName)) { 33662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount View view = sharedElements.remove(localName); 33762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (view != null) { 33862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount sharedElements.put(acceptedName, view); 33962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 34062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount } 341caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mount } 342caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mount } 34362ab9b78b77b7dd851c47115f4d8d7611d657585George Mount sharedElements.retainAll(mAllSharedElementNames); 34462ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mListener.remapSharedElements(mAllSharedElementNames, sharedElements); 34562ab9b78b77b7dd851c47115f4d8d7611d657585George Mount sharedElements.retainAll(mAllSharedElementNames); 34662ab9b78b77b7dd851c47115f4d8d7611d657585George Mount for (int i = 0; i < mAllSharedElementNames.size(); i++) { 34762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount String name = mAllSharedElementNames.get(i); 34862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount View sharedElement = sharedElements.get(name); 34962ab9b78b77b7dd851c47115f4d8d7611d657585George Mount if (sharedElement != null) { 35062ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mSharedElementNames.add(name); 35162ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mSharedElements.add(sharedElement); 352caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mount } 353caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mount } 354caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mount } 355caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mount } 356caa03107d4322b0e30f92e6dc1eb1ea73b1bf747George Mount 35762ab9b78b77b7dd851c47115f4d8d7611d657585George Mount protected void setResultReceiver(ResultReceiver resultReceiver) { 35862ab9b78b77b7dd851c47115f4d8d7611d657585George Mount mResultReceiver = resultReceiver; 359080443bcb63418245c2408500db735fece5e7083George Mount } 360080443bcb63418245c2408500db735fece5e7083George Mount 361a712e8cc2f16ac32ee5f1bbf5b962969f2f3451eGeorge Mount protected abstract Transition getViewsTransition(); 362080443bcb63418245c2408500db735fece5e7083George Mount 363c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount private static void setSharedElementState(View view, String name, Bundle transitionArgs, 364c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int[] parentLoc) { 365c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle sharedElementBundle = transitionArgs.getBundle(name); 366c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (sharedElementBundle == null) { 367c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return; 368c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 369c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 370c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (view instanceof ImageView) { 371c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int scaleTypeInt = sharedElementBundle.getInt(KEY_SCALE_TYPE, -1); 372c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (scaleTypeInt >= 0) { 373c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView imageView = (ImageView) view; 374c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView.ScaleType scaleType = SCALE_TYPE_VALUES[scaleTypeInt]; 375c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount imageView.setScaleType(scaleType); 376c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (scaleType == ImageView.ScaleType.MATRIX) { 377c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount float[] matrixValues = sharedElementBundle.getFloatArray(KEY_IMAGE_MATRIX); 378c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Matrix matrix = new Matrix(); 379c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount matrix.setValues(matrixValues); 380c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount imageView.setImageMatrix(matrix); 381c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 382c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 383c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 384c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 385c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount float z = sharedElementBundle.getFloat(KEY_TRANSLATION_Z); 386c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount view.setTranslationZ(z); 387c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 388c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int x = sharedElementBundle.getInt(KEY_SCREEN_X); 389c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int y = sharedElementBundle.getInt(KEY_SCREEN_Y); 390c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int width = sharedElementBundle.getInt(KEY_WIDTH); 391c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int height = sharedElementBundle.getInt(KEY_HEIGHT); 392c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 393c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); 394c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY); 395c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount view.measure(widthSpec, heightSpec); 396c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 397c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int left = x - parentLoc[0]; 398c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int top = y - parentLoc[1]; 399c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int right = left + width; 400c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int bottom = top + height; 401c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount view.layout(left, top, right, bottom); 402c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 403c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 404c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount protected ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>> setSharedElementState( 405c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle sharedElementState, final ArrayList<View> snapshots) { 406c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>> originalImageState = 407c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount new ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>>(); 408c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (sharedElementState != null) { 409c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int[] tempLoc = new int[2]; 410c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount for (int i = 0; i < mSharedElementNames.size(); i++) { 411c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount View sharedElement = mSharedElements.get(i); 412c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount String name = mSharedElementNames.get(i); 413c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Pair<ImageView.ScaleType, Matrix> originalState = getOldImageState(sharedElement, 414c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount name, sharedElementState); 415c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (originalState != null) { 416c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount originalImageState.put((ImageView) sharedElement, originalState); 417c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 418c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount View parent = (View) sharedElement.getParent(); 419c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount parent.getLocationOnScreen(tempLoc); 420c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount setSharedElementState(sharedElement, name, sharedElementState, tempLoc); 421c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 422c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 423c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount mListener.setSharedElementStart(mSharedElementNames, mSharedElements, snapshots); 424c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 425c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount getDecor().getViewTreeObserver().addOnPreDrawListener( 426c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount new ViewTreeObserver.OnPreDrawListener() { 427c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount @Override 428c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount public boolean onPreDraw() { 429c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount getDecor().getViewTreeObserver().removeOnPreDrawListener(this); 430c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount mListener.setSharedElementEnd(mSharedElementNames, mSharedElements, 431c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount snapshots); 432c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return true; 433c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 434c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 435c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ); 436c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return originalImageState; 437c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 438c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 439c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount private static Pair<ImageView.ScaleType, Matrix> getOldImageState(View view, String name, 440c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle transitionArgs) { 441c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (!(view instanceof ImageView)) { 442c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return null; 443c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 444c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle bundle = transitionArgs.getBundle(name); 445c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (bundle == null) { 446c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return null; 447c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 448c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int scaleTypeInt = bundle.getInt(KEY_SCALE_TYPE, -1); 449c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (scaleTypeInt < 0) { 450c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return null; 451c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 452c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 453c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView imageView = (ImageView) view; 454c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView.ScaleType originalScaleType = imageView.getScaleType(); 455c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 456c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Matrix originalMatrix = null; 457c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (originalScaleType == ImageView.ScaleType.MATRIX) { 458c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount originalMatrix = new Matrix(imageView.getImageMatrix()); 459c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 460c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 461c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return Pair.create(originalScaleType, originalMatrix); 462c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 463c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 464c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount protected ArrayList<View> createSnapshots(Bundle state, Collection<String> names) { 465c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int numSharedElements = names.size(); 466c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (numSharedElements == 0) { 467c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return null; 468c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 469c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ArrayList<View> snapshots = new ArrayList<View>(numSharedElements); 470c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Context context = getWindow().getContext(); 471c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int[] parentLoc = new int[2]; 472c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount getDecor().getLocationOnScreen(parentLoc); 473c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount for (String name: names) { 474c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle sharedElementBundle = state.getBundle(name); 475c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (sharedElementBundle != null) { 476c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bitmap bitmap = sharedElementBundle.getParcelable(KEY_BITMAP); 477c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount View snapshot = new View(context); 478c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Resources resources = getWindow().getContext().getResources(); 479c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (bitmap != null) { 480c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount snapshot.setBackground(new BitmapDrawable(resources, bitmap)); 481c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 482c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount snapshot.setViewName(name); 483c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount setSharedElementState(snapshot, name, state, parentLoc); 484c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount snapshots.add(snapshot); 485c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 486c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 487c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return snapshots; 488c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 489c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 490c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount protected static void setOriginalImageViewState( 491c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ArrayMap<ImageView, Pair<ImageView.ScaleType, Matrix>> originalState) { 492c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount for (int i = 0; i < originalState.size(); i++) { 493c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView imageView = originalState.keyAt(i); 494c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Pair<ImageView.ScaleType, Matrix> state = originalState.valueAt(i); 495c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount imageView.setScaleType(state.first); 496c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount imageView.setImageMatrix(state.second); 497c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 498c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 499c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 500c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount protected Bundle captureSharedElementState() { 501c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle bundle = new Bundle(); 5028e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount Rect tempBounds = new Rect(); 503c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount for (int i = 0; i < mSharedElementNames.size(); i++) { 504c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount View sharedElement = mSharedElements.get(i); 505c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount String name = mSharedElementNames.get(i); 5068e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount captureSharedElementState(sharedElement, name, bundle, tempBounds); 507c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 508c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return bundle; 509c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 510c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 511c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount /** 512c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * Captures placement information for Views with a shared element name for 513c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * Activity Transitions. 514c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * 515c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * @param view The View to capture the placement information for. 516c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * @param name The shared element name in the target Activity to apply the placement 517c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * information for. 518c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount * @param transitionArgs Bundle to store shared element placement information. 5198e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount * @param tempBounds A temporary Rect for capturing the current location of views. 520c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount */ 521c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount private static void captureSharedElementState(View view, String name, Bundle transitionArgs, 5228e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount Rect tempBounds) { 523c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bundle sharedElementBundle = new Bundle(); 5248e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount tempBounds.set(0, 0, view.getWidth(), view.getHeight()); 5258e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount view.getBoundsOnScreen(tempBounds); 5268e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount sharedElementBundle.putInt(KEY_SCREEN_X, tempBounds.left); 5278e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount int width = tempBounds.width(); 528c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementBundle.putInt(KEY_WIDTH, width); 529c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 5308e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount sharedElementBundle.putInt(KEY_SCREEN_Y, tempBounds.top); 5318e43d6d62fb3a94b2a7175d1dee3174c62f217baGeorge Mount int height = tempBounds.height(); 532c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementBundle.putInt(KEY_HEIGHT, height); 533c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 534c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ()); 535c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 536c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (width > 0 && height > 0) { 537c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 538c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount Canvas canvas = new Canvas(bitmap); 539c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount view.draw(canvas); 540c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementBundle.putParcelable(KEY_BITMAP, bitmap); 541c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 542c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 543c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (view instanceof ImageView) { 544c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount ImageView imageView = (ImageView) view; 545c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount int scaleTypeInt = scaleTypeToInt(imageView.getScaleType()); 546c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementBundle.putInt(KEY_SCALE_TYPE, scaleTypeInt); 547c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (imageView.getScaleType() == ImageView.ScaleType.MATRIX) { 548c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount float[] matrix = new float[9]; 549c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount imageView.getImageMatrix().getValues(matrix); 550c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount sharedElementBundle.putFloatArray(KEY_IMAGE_MATRIX, matrix); 551c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 552c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 553c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 554c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount transitionArgs.putBundle(name, sharedElementBundle); 555c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 556c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 557c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount private static int scaleTypeToInt(ImageView.ScaleType scaleType) { 558c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount for (int i = 0; i < SCALE_TYPE_VALUES.length; i++) { 559c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount if (scaleType == SCALE_TYPE_VALUES[i]) { 560c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return i; 561c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 562c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 563c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount return -1; 564c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount } 565c93ca1617397aace8449f88d1a1e94ec704a2ef4George Mount 56631a217290cf376d0573fc36e21c8940987485019George Mount private static class FixedEpicenterCallback extends Transition.EpicenterCallback { 56731a217290cf376d0573fc36e21c8940987485019George Mount private Rect mEpicenter; 56831a217290cf376d0573fc36e21c8940987485019George Mount 56931a217290cf376d0573fc36e21c8940987485019George Mount public void setEpicenter(Rect epicenter) { mEpicenter = epicenter; } 57031a217290cf376d0573fc36e21c8940987485019George Mount 57131a217290cf376d0573fc36e21c8940987485019George Mount @Override 572dc21d3b2804c24fe29ec860796d11185901364c4George Mount public Rect onGetEpicenter(Transition transition) { 57331a217290cf376d0573fc36e21c8940987485019George Mount return mEpicenter; 57431a217290cf376d0573fc36e21c8940987485019George Mount } 57531a217290cf376d0573fc36e21c8940987485019George Mount } 576800d72b0e05049e4a8f90ea96ec165fc975264ceGeorge Mount 57731a217290cf376d0573fc36e21c8940987485019George Mount} 578