Transition.java revision 31a217290cf376d0573fc36e21c8940987485019
1faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/* 2faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Copyright (C) 2013 The Android Open Source Project 3faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 4faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Licensed under the Apache License, Version 2.0 (the "License"); 5faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * you may not use this file except in compliance with the License. 6faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * You may obtain a copy of the License at 7faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 8faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * http://www.apache.org/licenses/LICENSE-2.0 9faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 10faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Unless required by applicable law or agreed to in writing, software 11faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * distributed under the License is distributed on an "AS IS" BASIS, 12faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * See the License for the specific language governing permissions and 14faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * limitations under the License. 15faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 166ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 17d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haasepackage android.transition; 18faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 19faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.Animator; 20faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.AnimatorListenerAdapter; 21faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.TimeInterpolator; 22d6107a3170df61d9e776fcd5666acfc9135c6f16George Mountimport android.graphics.Rect; 2308735185f8105710e18ad02297461bec9268e514Chet Haaseimport android.util.ArrayMap; 24c43524f3869cc0d36974fce61986017093f2ecd2Chet Haaseimport android.util.Log; 25faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.util.LongSparseArray; 26faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.util.SparseArray; 27d6107a3170df61d9e776fcd5666acfc9135c6f16George Mountimport android.util.SparseLongArray; 28faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.SurfaceView; 29faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.TextureView; 30faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.View; 31faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewGroup; 32faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewOverlay; 33cf68aad3164303df59b2a669d186a94533c9c743George Mountimport android.view.WindowId; 34faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.widget.ListView; 35ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haaseimport android.widget.Spinner; 36faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 37faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport java.util.ArrayList; 38d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haaseimport java.util.List; 39faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 40faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/** 41faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * A Transition holds information about animations that will be run on its 42faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * targets during a scene change. Subclasses of this abstract class may 43d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * choreograph several child transitions ({@link TransitionSet} or they may 44faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * perform custom animations themselves. Any Transition has two main jobs: 45faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (1) capture property values, and (2) play animations based on changes to 46faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * captured property values. A custom transition knows what property values 47faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on View objects are of interest to it, and also knows how to animate 48faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes to those values. For example, the {@link Fade} transition tracks 49faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes to visibility-related properties and is able to construct and run 50faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animations that fade items in or out based on changes to those properties. 51faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 52faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>Note: Transitions may not work correctly with either {@link SurfaceView} 53faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * or {@link TextureView}, due to the way that these views are displayed 54faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on the screen. For SurfaceView, the problem is that the view is updated from 55faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * a non-UI thread, so changes to the view due to transitions (such as moving 56faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * and resizing the view) may be out of sync with the display inside those bounds. 57faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * TextureView is more compatible with transitions in general, but some 58d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * specific transitions (such as {@link Fade}) may not be compatible 59faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * with TextureView because they rely on {@link ViewOverlay} functionality, 60faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * which does not currently work with TextureView.</p> 61d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 62d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Transitions can be declared in XML resource files inside the <code>res/transition</code> 63d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * directory. Transition resources consist of a tag name for one of the Transition 64d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * subclasses along with attributes to define some of the attributes of that transition. 65d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition: 66d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 67d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@sample development/samples/ApiDemos/res/transition/changebounds.xml ChangeBounds} 68d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 69d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * <p>{@link android.transition.Explode} transition:</p> 70d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 71d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@sample development/samples/ApiDemos/res/transition/explode.xml Explode} 72d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 73d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * <p>{@link android.transition.MoveImage} transition:</p> 74d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 75d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@sample development/samples/ApiDemos/res/transition/move_image.xml MoveImage} 76d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 77d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Note that attributes for the transition are not required, just as they are 78d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * optional when declared in code; Transitions created from XML resources will use 79d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * the same defaults as their code-created equivalents. Here is a slightly more 80d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * elaborate example which declares a {@link TransitionSet} transition with 81d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link ChangeBounds} and {@link Fade} child transitions:</p> 82d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 83d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@sample 84d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * development/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml TransitionSet} 85d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 86d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>In this example, the transitionOrdering attribute is used on the TransitionSet 87d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * object to change from the default {@link TransitionSet#ORDERING_TOGETHER} behavior 88d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * to be {@link TransitionSet#ORDERING_SEQUENTIAL} instead. Also, the {@link Fade} 89d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition uses a fadingMode of {@link Fade#OUT} instead of the default 90d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * out-in behavior. Finally, note the use of the <code>targets</code> sub-tag, which 91d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * takes a set of {@link android.R.styleable#TransitionTarget target} tags, each 92d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of which lists a specific <code>targetId</code> which this transition acts upon. 93d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Use of targets is optional, but can be used to either limit the time spent checking 94d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * attributes on unchanging views, or limiting the types of animations run on specific views. 95d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * In this case, we know that only the <code>grayscaleContainer</code> will be 96d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * disappearing, so we choose to limit the {@link Fade} transition to only that view.</p> 97d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 98d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Further information on XML resource descriptions for transitions can be found for 99d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet}, 100d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade}, and 101d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.R.styleable#Slide}. 102d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 103faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1046ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haasepublic abstract class Transition implements Cloneable { 105faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 106faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private static final String LOG_TAG = "Transition"; 107faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase static final boolean DBG = false; 108faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 109199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private String mName = getClass().getName(); 110199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 111faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long mStartDelay = -1; 112faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long mDuration = -1; 113faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TimeInterpolator mInterpolator = null; 114d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase ArrayList<Integer> mTargetIds = new ArrayList<Integer>(); 115d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase ArrayList<View> mTargets = new ArrayList<View>(); 116ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Integer> mTargetIdExcludes = null; 117ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<View> mTargetExcludes = null; 118ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Class> mTargetTypeExcludes = null; 119ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Integer> mTargetIdChildExcludes = null; 120ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<View> mTargetChildExcludes = null; 121ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Class> mTargetTypeChildExcludes = null; 1226ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private TransitionValuesMaps mStartValues = new TransitionValuesMaps(); 1236ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private TransitionValuesMaps mEndValues = new TransitionValuesMaps(); 124d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase TransitionSet mParent = null; 1256ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 126199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Per-animator information used for later canceling when future transitions overlap 127199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators = 128199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase new ThreadLocal<ArrayMap<Animator, AnimationInfo>>(); 129199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 130d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // Scene Root is set at createAnimator() time in the cloned Transition 1316ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase ViewGroup mSceneRoot = null; 1326ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 133b7a7fc9d233bad507ce893882352618b13647058Chet Haase // Whether removing views from their parent is possible. This is only for views 134b7a7fc9d233bad507ce893882352618b13647058Chet Haase // in the start scene, which are no longer in the view hierarchy. This property 135b7a7fc9d233bad507ce893882352618b13647058Chet Haase // is determined by whether the previous Scene was created from a layout 136b7a7fc9d233bad507ce893882352618b13647058Chet Haase // resource, and thus the views from the exited scene are going away anyway 137b7a7fc9d233bad507ce893882352618b13647058Chet Haase // and can be removed as necessary to achieve a particular effect, such as 138b7a7fc9d233bad507ce893882352618b13647058Chet Haase // removing them from parents to add them to overlays. 139b7a7fc9d233bad507ce893882352618b13647058Chet Haase boolean mCanRemoveViews = false; 140b7a7fc9d233bad507ce893882352618b13647058Chet Haase 141e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // Track all animators in use in case the transition gets canceled and needs to 142e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // cancel running animators 143e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase private ArrayList<Animator> mCurrentAnimators = new ArrayList<Animator>(); 144e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase 145faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Number of per-target instances of this Transition currently running. This count is 146199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // determined by calls to start() and end() 147faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int mNumInstances = 0; 148faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 149199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Whether this transition is currently paused, due to a call to pause() 150199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase boolean mPaused = false; 151c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase 152a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase // Whether this transition has ended. Used to avoid pause/resume on transitions 153a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase // that have completed 154a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase private boolean mEnded = false; 155a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase 156c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase // The set of listeners to be sent transition lifecycle events. 157faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> mListeners = null; 158faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 159d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // The set of animators collected from calls to createAnimator(), 160d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // to be run in runAnimators() 161199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayList<Animator> mAnimators = new ArrayList<Animator>(); 162c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase 163d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // The function for calculating the Animation start delay. 164d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount TransitionPropagation mPropagation; 165d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 166d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // The rectangular region for Transitions like Explode and TransitionPropagations 167d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // like CircularPropagation 168d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount EpicenterCallback mEpicenterCallback; 169d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 170faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 171faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Constructs a Transition object with no target objects. A transition with 172faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * no targets defaults to running on all target objects in the scene hierarchy 173d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * (if the transition is not contained in a TransitionSet), or all target 174d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * objects passed down from its parent (if it is in a TransitionSet). 175faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 176faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public Transition() {} 177faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 178faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 179faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the duration of this transition. By default, there is no duration 180faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (indicated by a negative number), which means that the Animator created by 181faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition will have its own specified duration. If the duration of a 182faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that duration will override the Animator duration. 183faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 184faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param duration The length of the animation, in milliseconds. 185faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return This transition object. 186d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_duration 187faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 188faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public Transition setDuration(long duration) { 189faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mDuration = duration; 190faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 191faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 192faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 193199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 194199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the duration set on this transition. If no duration has been set, 195199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be negative, indicating that resulting animators will 196199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own durations. 197199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 198d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The duration set on this transition, in milliseconds, if one has been 199d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * set, otherwise returns a negative number. 200199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 201faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public long getDuration() { 202faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mDuration; 203faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 204faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 205faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 206faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the startDelay of this transition. By default, there is no delay 207faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (indicated by a negative number), which means that the Animator created by 208faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition will have its own specified startDelay. If the delay of a 209faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that delay will override the Animator delay. 210faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 211faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param startDelay The length of the delay, in milliseconds. 212d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 213d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_startDelay 214faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 215d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition setStartDelay(long startDelay) { 216faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mStartDelay = startDelay; 217d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 218faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 219faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 220199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 221199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the startDelay set on this transition. If no startDelay has been set, 222199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be negative, indicating that resulting animators will 223199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own startDelays. 224199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 225d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The startDelay set on this transition, in milliseconds, if one has 226d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * been set, otherwise returns a negative number. 227199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 228faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public long getStartDelay() { 229faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mStartDelay; 230faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 231faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 232faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 233faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the interpolator of this transition. By default, the interpolator 234faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is null, which means that the Animator created by the transition 235faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will have its own specified interpolator. If the interpolator of a 236faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that interpolator will override the Animator interpolator. 237faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 238faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param interpolator The time interpolator used by the transition 239d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 240d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_interpolator 241faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 242d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition setInterpolator(TimeInterpolator interpolator) { 243faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mInterpolator = interpolator; 244d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 245faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 246faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 247199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 248199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the interpolator set on this transition. If no interpolator has been set, 249199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be null, indicating that resulting animators will 250199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own interpolators. 251199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 252199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return The interpolator set on this transition, if one has been set, otherwise 253199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * returns null. 254199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 255faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public TimeInterpolator getInterpolator() { 256faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mInterpolator; 257faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 258faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 259faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 260199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the set of property names used stored in the {@link TransitionValues} 261d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * object passed into {@link #captureStartValues(TransitionValues)} that 262199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * this transition cares about for the purposes of canceling overlapping animations. 263199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * When any transition is started on a given scene root, all transitions 264199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * currently running on that same scene root are checked to see whether the 265199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * properties on which they based their animations agree with the end values of 266199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the same properties in the new transition. If the end values are not equal, 267199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * then the old animation is canceled since the new transition will start a new 268199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation to these new values. If the values are equal, the old animation is 269199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * allowed to continue and no new animation is started for that transition. 270199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 271199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * <p>A transition does not need to override this method. However, not doing so 272199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * will mean that the cancellation logic outlined in the previous paragraph 273199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * will be skipped for that transition, possibly leading to artifacts as 274199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * old transitions and new transitions on the same targets run in parallel, 275199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animating views toward potentially different end values.</p> 276199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 277199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return An array of property names as described in the class documentation for 278199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * {@link TransitionValues}. The default implementation returns <code>null</code>. 279199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 280199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public String[] getTransitionProperties() { 281199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return null; 282199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 283199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 284199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 285d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * This method creates an animation that will be run for this transition 286d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * given the information in the startValues and endValues structures captured 287d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * earlier for the start and end scenes. Subclasses of Transition should override 288d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * this method. The method should only be called by the transition system; it is 289d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * not intended to be called from external classes. 290d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 291d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>This method is called by the transition's parent (all the way up to the 292faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * topmost Transition in the hierarchy) with the sceneRoot and start/end 2932ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * values that the transition may need to set up initial target values 2942ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * and construct an appropriate animation. For example, if an overall 295d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Transition is a {@link TransitionSet} consisting of several 296faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * child transitions in sequence, then some of the child transitions may 297faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * want to set initial values on target views prior to the overall 2982ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * Transition commencing, to put them in an appropriate state for the 299faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * delay between that start and the child Transition start time. For 300faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * example, a transition that fades an item in may wish to set the starting 301faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * alpha value to 0, to avoid it blinking in prior to the transition 302faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * actually starting the animation. This is necessary because the scene 303faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * change that triggers the Transition will automatically set the end-scene 304faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on all target views, so a Transition that wants to animate from a 305d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * different value should set that value prior to returning from this method.</p> 306faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 307faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>Additionally, a Transition can perform logic to determine whether 308faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition needs to run on the given target and start/end values. 309faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * For example, a transition that resizes objects on the screen may wish 310faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * to avoid running for views which are not present in either the start 311d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * or end scenes.</p> 3122ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * 3132ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <p>If there is an animator created and returned from this method, the 3142ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * transition mechanism will apply any applicable duration, startDelay, 3152ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * and interpolator to that animation and start it. A return value of 3162ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <code>null</code> indicates that no animation should run. The default 3172ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * implementation returns null.</p> 318faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 319faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>The method is called for every applicable target object, which is 320faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * stored in the {@link TransitionValues#view} field.</p> 321faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 322d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 323d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param sceneRoot The root of the transition hierarchy. 324d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param startValues The values for a specific target in the start scene. 325d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param endValues The values for the target in the end scene. 326d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return A Animator to be started at the appropriate time in the 327d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * overall transition for this scene change. A null value means no animation 328d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should be run. 329faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 330d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, 331faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues endValues) { 3322ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase return null; 333faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 334faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 335faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 336d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * This method, essentially a wrapper around all calls to createAnimator for all 337d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * possible target views, is called with the entire set of start/end 338faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * values. The implementation in Transition iterates through these lists 339d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)} 340faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * with each set of start/end values on this transition. The 341d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet subclass overrides this method and delegates it to 3422ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * each of its children in succession. 343faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 344faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 345faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 346d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues, 3476ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValuesMaps endValues) { 348c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 349d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Log.d(LOG_TAG, "createAnimators() for " + this); 350c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 3516ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase ArrayMap<View, TransitionValues> endCopy = 3526ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase new ArrayMap<View, TransitionValues>(endValues.viewValues); 353faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase SparseArray<TransitionValues> endIdCopy = 3546ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase new SparseArray<TransitionValues>(endValues.idValues.size()); 3556ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < endValues.idValues.size(); ++i) { 3566ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int id = endValues.idValues.keyAt(i); 3576ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase endIdCopy.put(id, endValues.idValues.valueAt(i)); 358faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 359faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase LongSparseArray<TransitionValues> endItemIdCopy = 3606ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase new LongSparseArray<TransitionValues>(endValues.itemIdValues.size()); 3616ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < endValues.itemIdValues.size(); ++i) { 3626ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase long id = endValues.itemIdValues.keyAt(i); 3636ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase endItemIdCopy.put(id, endValues.itemIdValues.valueAt(i)); 364faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 365faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Walk through the start values, playing everything we find 366faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Remove from the end set as we go 367faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionValues> startValuesList = new ArrayList<TransitionValues>(); 368faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionValues> endValuesList = new ArrayList<TransitionValues>(); 3696ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (View view : startValues.viewValues.keySet()) { 370faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues start = null; 371faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = null; 372faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase boolean isInListView = false; 373faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view.getParent() instanceof ListView) { 374faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase isInListView = true; 375faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 376faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (!isInListView) { 377faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int id = view.getId(); 3786ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase start = startValues.viewValues.get(view) != null ? 3796ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase startValues.viewValues.get(view) : startValues.idValues.get(id); 3806ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (endValues.viewValues.get(view) != null) { 3816ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase end = endValues.viewValues.get(view); 382faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endCopy.remove(view); 383c46181a963be736186ae29101625a05b5c1f0ba8Chet Haase } else if (id != View.NO_ID) { 3846ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase end = endValues.idValues.get(id); 385faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase View removeView = null; 386faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (View viewToRemove : endCopy.keySet()) { 387faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (viewToRemove.getId() == id) { 388faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase removeView = viewToRemove; 389faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 390faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 391faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (removeView != null) { 392faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endCopy.remove(removeView); 393faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 394faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 395faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endIdCopy.remove(id); 396faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isValidTarget(view, id)) { 397faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 398faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 399faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 400faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 401faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ListView parent = (ListView) view.getParent(); 402faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (parent.getAdapter().hasStableIds()) { 403faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int position = parent.getPositionForView(view); 404faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long itemId = parent.getItemIdAtPosition(position); 4056ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase start = startValues.itemIdValues.get(itemId); 406faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endItemIdCopy.remove(itemId); 407faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // TODO: deal with targetIDs for itemIDs for ListView items 408faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 409faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 410faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 411faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 412faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 4136ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int startItemIdCopySize = startValues.itemIdValues.size(); 414faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < startItemIdCopySize; ++i) { 4156ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase long id = startValues.itemIdValues.keyAt(i); 416faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isValidTarget(null, id)) { 4176ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues start = startValues.itemIdValues.get(id); 4186ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues end = endValues.itemIdValues.get(id); 419faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endItemIdCopy.remove(id); 420faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 421faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 422faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 423faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 424faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Now walk through the remains of the end set 425faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (View view : endCopy.keySet()) { 426faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int id = view.getId(); 427faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isValidTarget(view, id)) { 4286ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues start = startValues.viewValues.get(view) != null ? 4296ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase startValues.viewValues.get(view) : startValues.idValues.get(id); 430faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endCopy.get(view); 431faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endIdCopy.remove(id); 432faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 433faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 434faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 435faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 436faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int endIdCopySize = endIdCopy.size(); 437faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < endIdCopySize; ++i) { 438faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int id = endIdCopy.keyAt(i); 439faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isValidTarget(null, id)) { 4406ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues start = startValues.idValues.get(id); 441faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endIdCopy.get(id); 442faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 443faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 444faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 445faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 446faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int endItemIdCopySize = endItemIdCopy.size(); 447faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < endItemIdCopySize; ++i) { 448faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long id = endItemIdCopy.keyAt(i); 449faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // TODO: Deal with targetIDs and itemIDs 4506ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues start = startValues.itemIdValues.get(id); 451faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endItemIdCopy.get(id); 452faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 453faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 454faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 455199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 456d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount long minStartDelay = Long.MAX_VALUE; 457d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int minAnimator = mAnimators.size(); 458d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount SparseLongArray startDelays = new SparseLongArray(); 459faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < startValuesList.size(); ++i) { 460faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues start = startValuesList.get(i); 461faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endValuesList.get(i); 462c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase // Only bother trying to animate with values that differ between start/end 463c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (start != null || end != null) { 464c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (start == null || !start.equals(end)) { 465c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 466c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase View view = (end != null) ? end.view : start.view; 467c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Log.d(LOG_TAG, " differing start/end values for view " + 468c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase view); 469c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (start == null || end == null) { 470ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase Log.d(LOG_TAG, " " + ((start == null) ? 471ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase "start null, end non-null" : "start non-null, end null")); 472c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } else { 473c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase for (String key : start.values.keySet()) { 474c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Object startValue = start.values.get(key); 475c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Object endValue = end.values.get(key); 476c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (startValue != endValue && !startValue.equals(endValue)) { 477c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Log.d(LOG_TAG, " " + key + ": start(" + startValue + 478c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase "), end(" + endValue +")"); 479c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 480c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 481c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 482c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 483c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase // TODO: what to do about targetIds and itemIds? 484d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Animator animator = createAnimator(sceneRoot, start, end); 485c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (animator != null) { 486199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Save animation info for future cancellation purposes 487199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase View view = null; 488199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues infoValues = null; 489199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (end != null) { 490199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase view = end.view; 491199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase String[] properties = getTransitionProperties(); 492199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (view != null && properties != null && properties.length > 0) { 493199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase infoValues = new TransitionValues(); 494199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase infoValues.view = view; 495199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues newValues = endValues.viewValues.get(view); 496199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (newValues != null) { 497199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (int j = 0; j < properties.length; ++j) { 498199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase infoValues.values.put(properties[j], 499199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase newValues.values.get(properties[j])); 500199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 501199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 502199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase int numExistingAnims = runningAnimators.size(); 503199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (int j = 0; j < numExistingAnims; ++j) { 504199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Animator anim = runningAnimators.keyAt(j); 505199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase AnimationInfo info = runningAnimators.get(anim); 506199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (info.values != null && info.view == view && 507199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ((info.name == null && getName() == null) || 508199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase info.name.equals(getName()))) { 509199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (info.values.equals(infoValues)) { 510199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Favor the old animator 511199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase animator = null; 512199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase break; 513199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 514199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 515199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 516199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 517199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } else { 518199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase view = (start != null) ? start.view : null; 519199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 520199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (animator != null) { 521d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (mPropagation != null) { 522d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount long delay = mPropagation 523d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount .getStartDelay(sceneRoot, this, start, end); 524d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount startDelays.put(mAnimators.size(), delay); 525d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount minStartDelay = Math.min(delay, minStartDelay); 526d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 527cf68aad3164303df59b2a669d186a94533c9c743George Mount AnimationInfo info = new AnimationInfo(view, getName(), 528cf68aad3164303df59b2a669d186a94533c9c743George Mount sceneRoot.getWindowId(), infoValues); 529199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.put(animator, info); 530199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mAnimators.add(animator); 531199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 532c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 533c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 534faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 535faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 536d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (minStartDelay != 0) { 537d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount for (int i = 0; i < startDelays.size(); i++) { 538d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int index = startDelays.keyAt(i); 539d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount Animator animator = mAnimators.get(index); 540d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount long delay = startDelays.valueAt(i) - minStartDelay + animator.getStartDelay(); 541d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount animator.setStartDelay(delay); 542d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 543d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 544faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 545faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 546faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 547faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Internal utility method for checking whether a given view/id 548faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is valid for this transition, where "valid" means that either 549faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition has no target/targetId list (the default, in which 550faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * cause the transition should act on all views in the hiearchy), or 551faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the given view is in the target list or the view id is in the 552faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * targetId list. If the target parameter is null, then the target list 553faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is not checked (this is in the case of ListView items, where the 554faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * views are ignored and only the ids are used). 555faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 556faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase boolean isValidTarget(View target, long targetId) { 557ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdExcludes != null && mTargetIdExcludes.contains(targetId)) { 558ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 559ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 560ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetExcludes != null && mTargetExcludes.contains(target)) { 561ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 562ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 563ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes != null && target != null) { 564ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeExcludes.size(); 565ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 566ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase Class type = mTargetTypeExcludes.get(i); 567ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (type.isInstance(target)) { 568ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 569ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 570ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 571ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 572d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() == 0 && mTargets.size() == 0) { 573faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 574faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 575d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0) { 576d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargetIds.size(); ++i) { 577d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.get(i) == targetId) { 578faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 579faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 580faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 581faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 582d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (target != null && mTargets.size() > 0) { 583d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargets.size(); ++i) { 584d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargets.get(i) == target) { 585faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 586faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 587faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 588faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 589faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return false; 590faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 591faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 592e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() { 593199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get(); 594199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (runningAnimators == null) { 595199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators = new ArrayMap<Animator, AnimationInfo>(); 596199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase sRunningAnimators.set(runningAnimators); 597199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 598199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return runningAnimators; 599199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 600199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 601faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 6022ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * This is called internally once all animations have been set up by the 603d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * transition hierarchy. 604faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 605faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 606faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 607d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase protected void runAnimators() { 608199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 609d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Log.d(LOG_TAG, "runAnimators() on " + this); 610199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 611199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase start(); 612199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 613d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // Now start every Animator that was previously created for this transition 614199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (Animator anim : mAnimators) { 615c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 616c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Log.d(LOG_TAG, " anim: " + anim); 617c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 618199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (runningAnimators.containsKey(anim)) { 619199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase start(); 620199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runAnimator(anim, runningAnimators); 621199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 622faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 623199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mAnimators.clear(); 624199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 625faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 626faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 627199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private void runAnimator(Animator animator, 628199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase final ArrayMap<Animator, AnimationInfo> runningAnimators) { 629e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase if (animator != null) { 630e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // TODO: could be a single listener instance for all of them since it uses the param 631e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animator.addListener(new AnimatorListenerAdapter() { 632e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase @Override 633e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase public void onAnimationStart(Animator animation) { 634e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase mCurrentAnimators.add(animation); 635e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 636e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase @Override 637e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase public void onAnimationEnd(Animator animation) { 638199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.remove(animation); 639e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase mCurrentAnimators.remove(animation); 640e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 641e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase }); 642e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animate(animator); 643e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 644e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 645e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase 646faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 647d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Captures the values in the start scene for the properties that this 648d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition monitors. These values are then passed as the startValues 649d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * structure in a later call to 650d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 651d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The main concern for an implementation is what the 652d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * properties are that the transition cares about and what the values are 653d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * for all of those properties. The start and end values will be compared 654d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * later during the 655d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)} 656d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * method to determine what, if any, animations, should be run. 657d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 658d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Subclasses must implement this method. The method should only be called by the 659d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition system; it is not intended to be called from external classes.</p> 660d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 661d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param transitionValues The holder for any values that the Transition 662d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * wishes to store. Values are stored in the <code>values</code> field 663d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of this TransitionValues object and are keyed from 664d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * a String value. For example, to store a view's rotation value, 665d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * a transition might call 666d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionValues.values.put("appname:transitionname:rotation", 667d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * view.getRotation())</code>. The target view will already be stored in 668d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * the transitionValues structure when this method is called. 669d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 670d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #captureEndValues(TransitionValues) 671d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 672d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 673d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public abstract void captureStartValues(TransitionValues transitionValues); 674d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 675d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 676d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Captures the values in the end scene for the properties that this 677d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition monitors. These values are then passed as the endValues 678d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * structure in a later call to 679d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 680d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The main concern for an implementation is what the 681faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * properties are that the transition cares about and what the values are 682faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * for all of those properties. The start and end values will be compared 6832ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * later during the 684d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)} 6852ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * method to determine what, if any, animations, should be run. 686faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 687d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Subclasses must implement this method. The method should only be called by the 688d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition system; it is not intended to be called from external classes.</p> 689d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 6902ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * @param transitionValues The holder for any values that the Transition 6912ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * wishes to store. Values are stored in the <code>values</code> field 6922ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * of this TransitionValues object and are keyed from 6932ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * a String value. For example, to store a view's rotation value, 6942ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * a transition might call 6952ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <code>transitionValues.values.put("appname:transitionname:rotation", 6962ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * view.getRotation())</code>. The target view will already be stored in 6972ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * the transitionValues structure when this method is called. 698d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 699d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #captureStartValues(TransitionValues) 700d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 701faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 702d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public abstract void captureEndValues(TransitionValues transitionValues); 703faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 704faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 705d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Adds the id of a target view that this Transition is interested in 706faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animating. By default, there are no targetIds, and a Transition will 707faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listen for changes on every view in the hierarchy below the sceneRoot 708d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of the Scene being transitioned into. Setting targetIds constrains 709faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition to only listen for, and act on, views with these IDs. 710faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Views with different IDs, or no IDs whatsoever, will be ignored. 711faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 712d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Note that using ids to specify targets implies that ids should be unique 713d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * within the view hierarchy underneat the scene root.</p> 714d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 715faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @see View#getId() 716d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param targetId The id of a target view, must be a positive number. 717d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition to which the targetId is added. 718d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Returning the same object makes it easier to chain calls during 719d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * construction, such as 720ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <code>transitionSet.addTransitions(new Fade()).addTarget(someId);</code> 721d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 722ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition addTarget(int targetId) { 723d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (targetId > 0) { 724d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargetIds.add(targetId); 725d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 726d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 727d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 728d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 729d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 730d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Removes the given targetId from the list of ids that this Transition 731d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * is interested in animating. 732d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 733d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param targetId The id of a target view, must be a positive number. 734d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition from which the targetId is removed. 735faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returning the same object makes it easier to chain calls during 736faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * construction, such as 737d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code> 738faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 739ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition removeTarget(int targetId) { 740d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (targetId > 0) { 741d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargetIds.remove(targetId); 742d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 743faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 744faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 745faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 746faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 747ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given id to the list of target ids to exclude from this 748ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 749ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should be added to or removed from the excluded list. 750ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 751ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 752ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 753ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 754ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 755ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 756ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 757ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 758ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 759ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 760ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 761ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 762ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param targetId The id of a target to ignore when running this transition. 763ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 764ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 765ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 766ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 767ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(int targetId, boolean exclude) { 768ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetIdExcludes = excludeId(mTargetIdExcludes, targetId, exclude); 769ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 770ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 771ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 772ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 773ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the children of the given id to the list of targets to exclude 774ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * from this transition. The <code>exclude</code> parameter specifies whether 775ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the children of the target should be added to or removed from the excluded list. 776ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Excluding children in this way provides a simple mechanism for excluding all 777ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * children of specific targets, rather than individually excluding each 778ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * child individually. 779ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 780ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 781ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 782ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 783ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 784ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 785ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 786ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 787ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 788ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 789ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 790ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 791ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param targetId The id of a target whose children should be ignored when running 792ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * this transition. 793ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 794ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded-child targets. 795ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 796ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 797ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(int targetId, boolean exclude) { 798ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetIdChildExcludes = excludeId(mTargetIdChildExcludes, targetId, exclude); 799ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 800ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 801ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 802ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 803ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility method to manage the boilerplate code that is the same whether we 804ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * are excluding targets or their children. 805ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 806ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private ArrayList<Integer> excludeId(ArrayList<Integer> list, int targetId, boolean exclude) { 807ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (targetId > 0) { 808ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (exclude) { 809ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.add(list, targetId); 810ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } else { 811ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.remove(list, targetId); 812ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 813ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 814ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 815ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 816ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 817ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 818ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given target to the list of targets to exclude from this 819ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 820ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should be added to or removed from the excluded list. 821ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 822ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 823ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 824ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 825ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 826ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 827ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 828ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 829ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 830ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 831ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 832ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 833ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param target The target to ignore when running this transition. 834ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 835ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 836ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 837ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 838ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(View target, boolean exclude) { 839ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetExcludes = excludeView(mTargetExcludes, target, exclude); 840ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 841ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 842ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 843ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 844ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the children of given target to the list of target children 845ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * to exclude from this transition. The <code>exclude</code> parameter specifies 846ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * whether the target should be added to or removed from the excluded list. 847ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 848ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 849ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 850ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 851ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 852ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 853ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 854ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 855ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 856ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 857ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 858ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 859ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param target The target to ignore when running this transition. 860ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 861ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 862ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 863ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 864ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(View target, boolean exclude) { 865ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetChildExcludes = excludeView(mTargetChildExcludes, target, exclude); 866ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 867ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 868ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 869ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 870ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility method to manage the boilerplate code that is the same whether we 871ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * are excluding targets or their children. 872ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 873ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private ArrayList<View> excludeView(ArrayList<View> list, View target, boolean exclude) { 874ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (target != null) { 875ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (exclude) { 876ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.add(list, target); 877ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } else { 878ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.remove(list, target); 879ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 880ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 881ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 882ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 883ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 884ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 885ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given type to the list of types to exclude from this 886ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 887ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * type should be added to or removed from the excluded list. 888ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 889ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 890ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 891ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 892ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 893ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 894ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 895ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 896ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 897ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 898ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 899ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 900ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param type The type to ignore when running this transition. 901ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target type to or remove it from the 902ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded target types. 903ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 904ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 905ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(Class type, boolean exclude) { 906ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetTypeExcludes = excludeType(mTargetTypeExcludes, type, exclude); 907ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 908ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 909ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 910ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 911ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given type to the list of types whose children should 912ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * be excluded from this transition. The <code>exclude</code> parameter 913ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * specifies whether the target type should be added to or removed from 914ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the excluded list. 915ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 916ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 917ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 918ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 919ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 920ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 921ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 922ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 923ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 924ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 925ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 926ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 927ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param type The type to ignore when running this transition. 928ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target type to or remove it from the 929ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded target types. 930ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 931ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 932ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(Class type, boolean exclude) { 933ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetTypeChildExcludes = excludeType(mTargetTypeChildExcludes, type, exclude); 934ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 935ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 936ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 937ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 938ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility method to manage the boilerplate code that is the same whether we 939ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * are excluding targets or their children. 940ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 941ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private ArrayList<Class> excludeType(ArrayList<Class> list, Class type, boolean exclude) { 942ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (type != null) { 943ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (exclude) { 944ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.add(list, type); 945ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } else { 946ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.remove(list, type); 947ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 948ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 949ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 950ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 951ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 952ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 953faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the target view instances that this Transition is interested in 954faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animating. By default, there are no targets, and a Transition will 955faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listen for changes on every view in the hierarchy below the sceneRoot 956faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * of the Scene being transitioned into. Setting targets constrains 957faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition to only listen for, and act on, these views. 958faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * All other views will be ignored. 959faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 960ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>The target list is like the {@link #addTarget(int) targetId} 961faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * list except this list specifies the actual View instances, not the ids 962faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * of the views. This is an important distinction when scene changes involve 963faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * view hierarchies which have been inflated separately; different views may 964faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * share the same id but not actually be the same instance. If the transition 965ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should treat those views as the same, then {@link #addTarget(int)} should be used 966d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve 967faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes all within the same view hierarchy, among views which do not 968d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * necessarily have ids set on them, then the target list of views may be more 969faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * convenient.</p> 970faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 971ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #addTarget(int) 972d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param target A View on which the Transition will act, must be non-null. 973d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition to which the target is added. 974d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Returning the same object makes it easier to chain calls during 975d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * construction, such as 976d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code> 977d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 978d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition addTarget(View target) { 979d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargets.add(target); 980d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 981d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 982d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 983d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 984d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Removes the given target from the list of targets that this Transition 985d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * is interested in animating. 986d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 987d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param target The target view, must be non-null. 988d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return Transition The Transition from which the target is removed. 989faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returning the same object makes it easier to chain calls during 990faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * construction, such as 991d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code> 992faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 993d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition removeTarget(View target) { 994d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (target != null) { 995d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargets.remove(target); 996d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 997faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 998faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 999faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1000faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1001faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returns the array of target IDs that this transition limits itself to 1002faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * tracking and animating. If the array is null for both this method and 1003faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * {@link #getTargets()}, then this transition is 1004faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * not limited to specific views, and will handle changes to any views 1005faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * in the hierarchy of a scene change. 1006faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1007faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return the list of target IDs 1008faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1009d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public List<Integer> getTargetIds() { 1010faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mTargetIds; 1011faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1012faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1013faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1014faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returns the array of target views that this transition limits itself to 1015faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * tracking and animating. If the array is null for both this method and 1016faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * {@link #getTargetIds()}, then this transition is 1017faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * not limited to specific views, and will handle changes to any views 1018faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * in the hierarchy of a scene change. 1019faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1020faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return the list of target views 1021faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1022d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public List<View> getTargets() { 1023faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mTargets; 1024faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1025faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1026faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1027faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Recursive method that captures values for the given view and the 1028faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * hierarchy underneath it. 1029faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param sceneRoot The root of the view hierarchy being captured 1030faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param start true if this capture is happening before the scene change, 1031faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * false otherwise 1032faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1033faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void captureValues(ViewGroup sceneRoot, boolean start) { 1034df32aa87150768795816852c6393306893467ecaChet Haase clearValues(start); 1035d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0 || mTargets.size() > 0) { 1036d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0) { 1037d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargetIds.size(); ++i) { 1038d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase int id = mTargetIds.get(i); 1039faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase View view = sceneRoot.findViewById(id); 1040faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view != null) { 1041faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues values = new TransitionValues(); 1042faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase values.view = view; 1043d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (start) { 1044d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureStartValues(values); 1045d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } else { 1046d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureEndValues(values); 1047d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 1048d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount capturePropagationValues(values); 1049faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (start) { 10506ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mStartValues.viewValues.put(view, values); 1051867a86613d4152a93423300f83597300e6ebeebeChet Haase if (id >= 0) { 10526ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mStartValues.idValues.put(id, values); 1053867a86613d4152a93423300f83597300e6ebeebeChet Haase } 1054faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 10556ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mEndValues.viewValues.put(view, values); 1056867a86613d4152a93423300f83597300e6ebeebeChet Haase if (id >= 0) { 10576ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mEndValues.idValues.put(id, values); 1058867a86613d4152a93423300f83597300e6ebeebeChet Haase } 1059faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1060faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1061faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1062faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1063d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargets.size() > 0) { 1064d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargets.size(); ++i) { 1065d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase View view = mTargets.get(i); 1066faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view != null) { 1067faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues values = new TransitionValues(); 1068faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase values.view = view; 1069d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (start) { 1070d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureStartValues(values); 1071d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } else { 1072d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureEndValues(values); 1073d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 1074d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount capturePropagationValues(values); 1075faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (start) { 10766ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mStartValues.viewValues.put(view, values); 1077faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 10786ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mEndValues.viewValues.put(view, values); 1079faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1080faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1081faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1082faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1083faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1084faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase captureHierarchy(sceneRoot, start); 1085faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1086faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1087faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1088faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1089df32aa87150768795816852c6393306893467ecaChet Haase * Clear valuesMaps for specified start/end state 1090df32aa87150768795816852c6393306893467ecaChet Haase * 1091df32aa87150768795816852c6393306893467ecaChet Haase * @param start true if the start values should be cleared, false otherwise 1092df32aa87150768795816852c6393306893467ecaChet Haase */ 1093df32aa87150768795816852c6393306893467ecaChet Haase void clearValues(boolean start) { 1094df32aa87150768795816852c6393306893467ecaChet Haase if (start) { 1095df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.viewValues.clear(); 1096df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.idValues.clear(); 1097df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.itemIdValues.clear(); 1098df32aa87150768795816852c6393306893467ecaChet Haase } else { 1099df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.viewValues.clear(); 1100df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.idValues.clear(); 1101df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.itemIdValues.clear(); 1102df32aa87150768795816852c6393306893467ecaChet Haase } 1103df32aa87150768795816852c6393306893467ecaChet Haase } 1104df32aa87150768795816852c6393306893467ecaChet Haase 1105df32aa87150768795816852c6393306893467ecaChet Haase /** 1106faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Recursive method which captures values for an entire view hierarchy, 1107faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * starting at some root view. Transitions without targetIDs will use this 1108faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * method to capture values for all possible views. 1109faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1110faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param view The view for which to capture values. Children of this View 1111faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will also be captured, recursively down to the leaf nodes. 1112faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param start true if values are being captured in the start scene, false 1113faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * otherwise. 1114faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1115faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private void captureHierarchy(View view, boolean start) { 1116faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view == null) { 1117faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return; 1118faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 11190a778eda690a66173733a63622886e888d405c45George Mount if (!isValidTarget(view, view.getId())) { 11200a778eda690a66173733a63622886e888d405c45George Mount return; 11210a778eda690a66173733a63622886e888d405c45George Mount } 1122faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase boolean isListViewItem = false; 1123faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view.getParent() instanceof ListView) { 1124faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase isListViewItem = true; 1125faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1126faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isListViewItem && !((ListView) view.getParent()).getAdapter().hasStableIds()) { 1127faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // ignore listview children unless we can track them with stable IDs 1128faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return; 1129faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1130ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int id = View.NO_ID; 1131ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase long itemId = View.NO_ID; 1132faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (!isListViewItem) { 1133faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase id = view.getId(); 1134faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1135faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ListView listview = (ListView) view.getParent(); 1136faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int position = listview.getPositionForView(view); 1137ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase itemId = listview.getItemIdAtPosition(position); 1138faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase view.setHasTransientState(true); 1139faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1140ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdExcludes != null && mTargetIdExcludes.contains(id)) { 1141ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1142ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1143ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetExcludes != null && mTargetExcludes.contains(view)) { 1144ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1145ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1146ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes != null && view != null) { 1147ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeExcludes.size(); 1148ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 1149ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes.get(i).isInstance(view)) { 1150ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1151ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1152ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1153ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1154e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (view.getParent() instanceof ViewGroup) { 1155e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount TransitionValues values = new TransitionValues(); 1156e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount values.view = view; 1157e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (start) { 1158e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount captureStartValues(values); 1159faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1160e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount captureEndValues(values); 1161faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1162d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount capturePropagationValues(values); 1163e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (start) { 1164e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (!isListViewItem) { 1165e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount mStartValues.viewValues.put(view, values); 1166e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (id >= 0) { 1167e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount mStartValues.idValues.put((int) id, values); 1168e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount } 1169e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount } else { 1170e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount mStartValues.itemIdValues.put(itemId, values); 1171867a86613d4152a93423300f83597300e6ebeebeChet Haase } 1172faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1173e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (!isListViewItem) { 1174e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount mEndValues.viewValues.put(view, values); 1175e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (id >= 0) { 1176e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount mEndValues.idValues.put((int) id, values); 1177e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount } 1178e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount } else { 1179e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount mEndValues.itemIdValues.put(itemId, values); 1180e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount } 1181faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1182faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1183faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view instanceof ViewGroup) { 1184ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase // Don't traverse child hierarchy if there are any child-excludes on this view 1185ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdChildExcludes != null && mTargetIdChildExcludes.contains(id)) { 1186ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1187ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1188ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetChildExcludes != null && mTargetChildExcludes.contains(view)) { 1189ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1190ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1191ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeChildExcludes != null && view != null) { 1192ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeChildExcludes.size(); 1193ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 1194ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeChildExcludes.get(i).isInstance(view)) { 1195ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1196ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1197ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1198ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1199faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ViewGroup parent = (ViewGroup) view; 1200faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < parent.getChildCount(); ++i) { 1201faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase captureHierarchy(parent.getChildAt(i), start); 1202faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1203faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1204faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1205faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1206faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 12076ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * This method can be called by transitions to get the TransitionValues for 12086ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * any particular view during the transition-playing process. This might be 12096ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * necessary, for example, to query the before/after state of related views 12106ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * for a given transition. 12116ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase */ 1212d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public TransitionValues getTransitionValues(View view, boolean start) { 12136ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (mParent != null) { 12146ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return mParent.getTransitionValues(view, start); 12156ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 12166ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValuesMaps valuesMaps = start ? mStartValues : mEndValues; 12176ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues values = valuesMaps.viewValues.get(view); 12186ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (values == null) { 12196ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int id = view.getId(); 12206ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (id >= 0) { 12216ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase values = valuesMaps.idValues.get(id); 12226ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 12236ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (values == null && view.getParent() instanceof ListView) { 12246ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase ListView listview = (ListView) view.getParent(); 12256ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int position = listview.getPositionForView(view); 12266ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase long itemId = listview.getItemIdAtPosition(position); 12276ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase values = valuesMaps.itemIdValues.get(itemId); 12286ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 12296ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase // TODO: Doesn't handle the case where a view was parented to a 12306ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase // ListView (with an itemId), but no longer is 12316ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 12326ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return values; 12336ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 12346ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 12356ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase /** 1236199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Pauses this transition, sending out calls to {@link 1237199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * TransitionListener#onTransitionPause(Transition)} to all listeners 1238199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * and pausing all running animators started by this transition. 1239199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1240199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @hide 1241199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1242cf68aad3164303df59b2a669d186a94533c9c743George Mount public void pause(View sceneRoot) { 1243a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (!mEnded) { 1244a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1245a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numOldAnims = runningAnimators.size(); 1246cf68aad3164303df59b2a669d186a94533c9c743George Mount WindowId windowId = sceneRoot.getWindowId(); 1247a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1248cf68aad3164303df59b2a669d186a94533c9c743George Mount AnimationInfo info = runningAnimators.valueAt(i); 1249cf68aad3164303df59b2a669d186a94533c9c743George Mount if (info.view != null && windowId.equals(info.windowId)) { 1250cf68aad3164303df59b2a669d186a94533c9c743George Mount Animator anim = runningAnimators.keyAt(i); 1251cf68aad3164303df59b2a669d186a94533c9c743George Mount anim.pause(); 1252cf68aad3164303df59b2a669d186a94533c9c743George Mount } 1253a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1254a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (mListeners != null && mListeners.size() > 0) { 1255a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayList<TransitionListener> tmpListeners = 1256a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1257a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numListeners = tmpListeners.size(); 1258a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = 0; i < numListeners; ++i) { 1259a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase tmpListeners.get(i).onTransitionPause(this); 1260a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1261199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1262a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mPaused = true; 1263199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1264199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1265199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1266199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1267199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Resumes this transition, sending out calls to {@link 1268199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * TransitionListener#onTransitionPause(Transition)} to all listeners 1269199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * and pausing all running animators started by this transition. 1270199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1271199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @hide 1272199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1273cf68aad3164303df59b2a669d186a94533c9c743George Mount public void resume(View sceneRoot) { 1274199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (mPaused) { 1275a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (!mEnded) { 1276a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1277a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numOldAnims = runningAnimators.size(); 1278cf68aad3164303df59b2a669d186a94533c9c743George Mount WindowId windowId = sceneRoot.getWindowId(); 1279a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1280cf68aad3164303df59b2a669d186a94533c9c743George Mount AnimationInfo info = runningAnimators.valueAt(i); 1281cf68aad3164303df59b2a669d186a94533c9c743George Mount if (info.view != null && windowId.equals(info.windowId)) { 1282cf68aad3164303df59b2a669d186a94533c9c743George Mount Animator anim = runningAnimators.keyAt(i); 1283cf68aad3164303df59b2a669d186a94533c9c743George Mount anim.resume(); 1284cf68aad3164303df59b2a669d186a94533c9c743George Mount } 1285a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1286a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (mListeners != null && mListeners.size() > 0) { 1287a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayList<TransitionListener> tmpListeners = 1288a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1289a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numListeners = tmpListeners.size(); 1290a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = 0; i < numListeners; ++i) { 1291a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase tmpListeners.get(i).onTransitionResume(this); 1292a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1293199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1294199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1295199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mPaused = false; 1296199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1297199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1298199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1299199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1300faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Called by TransitionManager to play the transition. This calls 1301d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimators() to set things up and create all of the animations and then 13022ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * runAnimations() to actually start the animations. 1303faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 13046ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase void playTransition(ViewGroup sceneRoot) { 1305199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1306199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase int numOldAnims = runningAnimators.size(); 1307199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1308199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Animator anim = runningAnimators.keyAt(i); 1309199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (anim != null) { 1310199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase AnimationInfo oldInfo = runningAnimators.get(anim); 131158ad12208afcf9fdce735dead8449c4db375344dChet Haase if (oldInfo != null && oldInfo.view != null && 131258ad12208afcf9fdce735dead8449c4db375344dChet Haase oldInfo.view.getContext() == sceneRoot.getContext()) { 1313199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase boolean cancel = false; 1314199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues oldValues = oldInfo.values; 1315199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase View oldView = oldInfo.view; 1316199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues newValues = mEndValues.viewValues != null ? 1317199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mEndValues.viewValues.get(oldView) : null; 131823c61f6bc57a611d97d333bce0d8fe00ab81af4cChet Haase if (newValues == null) { 131923c61f6bc57a611d97d333bce0d8fe00ab81af4cChet Haase newValues = mEndValues.idValues.get(oldView.getId()); 132023c61f6bc57a611d97d333bce0d8fe00ab81af4cChet Haase } 1321af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (oldValues != null) { 1322af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase // if oldValues null, then transition didn't care to stash values, 1323af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase // and won't get canceled 132423c61f6bc57a611d97d333bce0d8fe00ab81af4cChet Haase if (newValues != null) { 1325af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase for (String key : oldValues.values.keySet()) { 1326af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase Object oldValue = oldValues.values.get(key); 1327af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase Object newValue = newValues.values.get(key); 1328af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (oldValue != null && newValue != null && 1329af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase !oldValue.equals(newValue)) { 1330af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase cancel = true; 1331af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (DBG) { 1332af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase Log.d(LOG_TAG, "Transition.playTransition: " + 1333af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase "oldValue != newValue for " + key + 1334af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase ": old, new = " + oldValue + ", " + newValue); 1335af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase } 1336af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase break; 1337199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1338199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1339199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1340199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1341199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (cancel) { 1342199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (anim.isRunning() || anim.isStarted()) { 1343199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 1344199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Log.d(LOG_TAG, "Canceling anim " + anim); 1345199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1346199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase anim.cancel(); 1347199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } else { 1348199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 1349199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Log.d(LOG_TAG, "removing anim from info list: " + anim); 1350199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1351199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.remove(anim); 1352199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1353199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1354199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1355199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1356199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1357199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1358d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase createAnimators(sceneRoot, mStartValues, mEndValues); 1359d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase runAnimators(); 1360faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1361faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1362faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1363faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This is a utility method used by subclasses to handle standard parts of 1364faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * setting up and running an Animator: it sets the {@link #getDuration() 1365faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * duration} and the {@link #getStartDelay() startDelay}, starts the 1366199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation, and, when the animator ends, calls {@link #end()}. 1367faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1368faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param animator The Animator to be run during this transition. 1369faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1370faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1371faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1372faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase protected void animate(Animator animator) { 1373faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // TODO: maybe pass auto-end as a boolean parameter? 1374faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (animator == null) { 1375199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 1376faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1377faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getDuration() >= 0) { 1378faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.setDuration(getDuration()); 1379faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1380faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getStartDelay() >= 0) { 1381d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount animator.setStartDelay(getStartDelay() + animator.getStartDelay()); 1382faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1383faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getInterpolator() != null) { 1384faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.setInterpolator(getInterpolator()); 1385faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1386faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.addListener(new AnimatorListenerAdapter() { 1387faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1388faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onAnimationEnd(Animator animation) { 1389199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 1390faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animation.removeListener(this); 1391faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1392faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase }); 1393faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.start(); 1394faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1395faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1396faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1397faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1398faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method is called automatically by the transition and 1399d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet classes prior to a Transition subclass starting; 1400faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * subclasses should not need to call it directly. 1401faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1402faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1403faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1404199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void start() { 1405faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mNumInstances == 0) { 1406faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1407faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1408faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1409faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1410faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1411faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionStart(this); 1412faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1413faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1414a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mEnded = false; 1415faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1416faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mNumInstances++; 1417faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1418faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1419faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1420faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method is called automatically by the Transition and 1421d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet classes when a transition finishes, either because 1422faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * a transition did nothing (returned a null Animator from 1423d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link Transition#createAnimator(ViewGroup, TransitionValues, 1424faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * TransitionValues)}) or because the transition returned a valid 1425199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Animator and end() was called in the onAnimationEnd() 1426faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * callback of the AnimatorListener. 1427faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1428faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1429faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1430199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void end() { 1431faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase --mNumInstances; 1432faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mNumInstances == 0) { 1433faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1434faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1435faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1436faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1437faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1438faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionEnd(this); 1439faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1440faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 14416ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < mStartValues.itemIdValues.size(); ++i) { 14426ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues tv = mStartValues.itemIdValues.valueAt(i); 1443faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase View v = tv.view; 1444faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (v.hasTransientState()) { 1445faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase v.setHasTransientState(false); 1446faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1447faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 14486ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < mEndValues.itemIdValues.size(); ++i) { 14496ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues tv = mEndValues.itemIdValues.valueAt(i); 1450faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase View v = tv.view; 1451faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (v.hasTransientState()) { 1452faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase v.setHasTransientState(false); 1453faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1454faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1455a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mEnded = true; 1456faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1457faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1458faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1459faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1460faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method cancels a transition that is currently running. 1461d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 1462d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @hide 1463faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1464199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void cancel() { 1465e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase int numAnimators = mCurrentAnimators.size(); 146625a738fb257aacfc87d3363a834ed6e0b050c3b1Chet Haase for (int i = numAnimators - 1; i >= 0; i--) { 1467e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase Animator animator = mCurrentAnimators.get(i); 1468e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animator.cancel(); 1469e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 1470faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1471faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1472faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1473faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1474faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1475faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionCancel(this); 1476faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1477faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1478faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1479faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1480faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1481faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Adds a listener to the set of listeners that are sent events through the 1482faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * life of an animation, such as start, repeat, and end. 1483faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1484faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param listener the listener to be added to the current set of listeners 1485faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * for this animation. 1486d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 1487faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1488d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition addListener(TransitionListener listener) { 1489faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners == null) { 1490faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners = new ArrayList<TransitionListener>(); 1491faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1492faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners.add(listener); 1493d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1494faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1495faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1496faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1497faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Removes a listener from the set listening to this animation. 1498faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1499faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param listener the listener to be removed from the current set of 1500faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listeners for this transition. 1501d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 1502faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1503d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition removeListener(TransitionListener listener) { 1504faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners == null) { 1505d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1506faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1507faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners.remove(listener); 1508faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners.size() == 0) { 1509faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners = null; 1510faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1511d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1512faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1513faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1514d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1515d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Sets the callback to use to find the epicenter of a Transition. A null value indicates 1516d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * that there is no epicenter in the Transition and getEpicenter() will return null. 1517d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Transitions like {@link android.transition.Explode} use a point or Rect to orient 1518d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the direction of travel. This is called the epicenter of the Transition and is 1519d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * typically centered on a touched View. The 1520d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} allows a Transition to 1521d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * dynamically retrieve the epicenter during a Transition. 1522d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param epicenterCallback The callback to use to find the epicenter of the Transition. 1523d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1524d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void setEpicenterCallback(EpicenterCallback epicenterCallback) { 1525d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mEpicenterCallback = epicenterCallback; 1526d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1527d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1528d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1529d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Returns the callback used to find the epicenter of the Transition. 1530d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Transitions like {@link android.transition.Explode} use a point or Rect to orient 1531d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the direction of travel. This is called the epicenter of the Transition and is 1532d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * typically centered on a touched View. The 1533d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} allows a Transition to 1534d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * dynamically retrieve the epicenter during a Transition. 1535d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return the callback used to find the epicenter of the Transition. 1536d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1537d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public EpicenterCallback getEpicenterCallback() { 1538d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return mEpicenterCallback; 1539d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1540d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1541d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1542d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Returns the epicenter as specified by the 1543d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists. 1544d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return the epicenter as specified by the 1545d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists. 1546d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback) 1547d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1548d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public Rect getEpicenter() { 1549d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (mEpicenterCallback == null) { 1550d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return null; 1551d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1552d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return mEpicenterCallback.getEpicenter(this); 1553d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1554d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1555d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1556d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Sets the method for determining Animator start delays. 1557d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * When a Transition affects several Views like {@link android.transition.Explode} or 1558d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect 1559d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * such that the Animator start delay depends on position of the View. The 1560d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * TransitionPropagation specifies how the start delays are calculated. 1561d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param transitionPropagation The class used to determine the start delay of 1562d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Animators created by this Transition. A null value 1563d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * indicates that no delay should be used. 1564d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1565d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void setPropagation(TransitionPropagation transitionPropagation) { 1566d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mPropagation = transitionPropagation; 1567d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1568d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1569d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1570d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Returns the {@link android.transition.TransitionPropagation} used to calculate Animator start 1571d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * delays. 1572d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * When a Transition affects several Views like {@link android.transition.Explode} or 1573d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect 1574d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * such that the Animator start delay depends on position of the View. The 1575d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * TransitionPropagation specifies how the start delays are calculated. 1576d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return the {@link android.transition.TransitionPropagation} used to calculate Animator start 1577d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * delays. This is null by default. 1578d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1579d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public TransitionPropagation getPropagation() { 1580d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return mPropagation; 1581d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1582d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1583d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1584d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Captures TransitionPropagation values for the given view and the 1585d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * hierarchy underneath it. 1586d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1587d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount void capturePropagationValues(TransitionValues transitionValues) { 158831a217290cf376d0573fc36e21c8940987485019George Mount if (mPropagation != null && !transitionValues.values.isEmpty()) { 1589d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount String[] propertyNames = mPropagation.getPropagationProperties(); 1590d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (propertyNames == null) { 1591d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return; 1592d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1593d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount boolean containsAll = true; 1594d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount for (int i = 0; i < propertyNames.length; i++) { 1595d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (!transitionValues.values.containsKey(propertyNames[i])) { 1596d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount containsAll = false; 1597d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount break; 1598d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1599d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1600d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (!containsAll) { 1601d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mPropagation.captureValues(transitionValues); 1602d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1603d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1604d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1605d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1606d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Transition setSceneRoot(ViewGroup sceneRoot) { 16076ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mSceneRoot = sceneRoot; 1608d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 16096ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 16106ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 1611b7a7fc9d233bad507ce893882352618b13647058Chet Haase void setCanRemoveViews(boolean canRemoveViews) { 1612b7a7fc9d233bad507ce893882352618b13647058Chet Haase mCanRemoveViews = canRemoveViews; 1613b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 1614b7a7fc9d233bad507ce893882352618b13647058Chet Haase 16150a778eda690a66173733a63622886e888d405c45George Mount public boolean canRemoveViews() { 16160a778eda690a66173733a63622886e888d405c45George Mount return mCanRemoveViews; 16170a778eda690a66173733a63622886e888d405c45George Mount } 16180a778eda690a66173733a63622886e888d405c45George Mount 1619faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1620faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public String toString() { 1621faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return toString(""); 1622faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1623faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 16246ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase @Override 16256ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase public Transition clone() { 16266ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase Transition clone = null; 16276ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase try { 16286ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase clone = (Transition) super.clone(); 1629199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase clone.mAnimators = new ArrayList<Animator>(); 16307660d121b2ef21164ed33e6091e5dd50f5d0f939Chet Haase clone.mStartValues = new TransitionValuesMaps(); 16317660d121b2ef21164ed33e6091e5dd50f5d0f939Chet Haase clone.mEndValues = new TransitionValuesMaps(); 16326ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } catch (CloneNotSupportedException e) {} 16336ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 16346ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return clone; 16356ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 16366ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 1637199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1638199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the name of this Transition. This name is used internally to distinguish 1639199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * between different transitions to determine when interrupting transitions overlap. 1640d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * For example, a ChangeBounds running on the same target view as another ChangeBounds 1641d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should determine whether the old transition is animating to different end values 1642d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * and should be canceled in favor of the new transition. 1643199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1644199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * <p>By default, a Transition's name is simply the value of {@link Class#getName()}, 1645199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * but subclasses are free to override and return something different.</p> 1646199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1647199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return The name of this transition. 1648199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1649199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public String getName() { 1650199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return mName; 1651199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1652199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1653faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase String toString(String indent) { 1654faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase String result = indent + getClass().getSimpleName() + "@" + 1655faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase Integer.toHexString(hashCode()) + ": "; 1656c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mDuration != -1) { 1657c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "dur(" + mDuration + ") "; 1658c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1659c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mStartDelay != -1) { 1660c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "dly(" + mStartDelay + ") "; 1661c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1662c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mInterpolator != null) { 1663c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "interp(" + mInterpolator + ") "; 1664c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1665d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0 || mTargets.size() > 0) { 1666c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "tgts("; 1667d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0) { 1668d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargetIds.size(); ++i) { 1669c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (i > 0) { 1670c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ", "; 1671c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1672d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase result += mTargetIds.get(i); 1673faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1674faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1675d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargets.size() > 0) { 1676d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargets.size(); ++i) { 1677c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (i > 0) { 1678c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ", "; 1679c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1680d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase result += mTargets.get(i); 1681faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1682faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1683c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ")"; 1684faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1685faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return result; 1686faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1687faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1688faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1689faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * A transition listener receives notifications from a transition. 1690199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notifications indicate transition lifecycle events. 1691faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1692faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public static interface TransitionListener { 1693faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1694faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the start of the transition. 1695faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1696faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The started transition. 1697faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1698faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionStart(Transition transition); 1699faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1700faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1701faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the end of the transition. Canceled transitions 1702faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will always notify listeners of both the cancellation and end 1703199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * events. That is, {@link #onTransitionEnd(Transition)} is always called, 1704faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * regardless of whether the transition was canceled or played 1705faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * through to completion. 1706faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1707faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The transition which reached its end. 1708faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1709faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionEnd(Transition transition); 1710faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1711faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1712faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the cancellation of the transition. 1713d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that cancel may be called by a parent {@link TransitionSet} on 1714199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 1715199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state on target objects which was set at 1716d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 1717d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimator()} time. 1718faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1719faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The transition which was canceled. 1720faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1721faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionCancel(Transition transition); 1722199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1723199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1724199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notification when a transition is paused. 1725d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that createAnimator() may be called by a parent {@link TransitionSet} on 1726199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 1727199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state on target objects which was set at 1728d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 1729d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimator()} time. 1730199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1731199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @param transition The transition which was paused. 1732199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1733199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase void onTransitionPause(Transition transition); 1734199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1735199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1736199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notification when a transition is resumed. 1737d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that resume() may be called by a parent {@link TransitionSet} on 1738199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 1739199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state which may have changed in an earlier call 1740199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * to {@link #onTransitionPause(Transition)}. 1741199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1742199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @param transition The transition which was resumed. 1743199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1744199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase void onTransitionResume(Transition transition); 1745faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1746faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1747faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1748faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Utility adapter class to avoid having to override all three methods 1749faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * whenever someone just wants to listen for a single event. 1750faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1751faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1752faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * */ 1753faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public static class TransitionListenerAdapter implements TransitionListener { 1754faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1755faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionStart(Transition transition) { 1756faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1757faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1758faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1759faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionEnd(Transition transition) { 1760faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1761faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1762faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1763faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionCancel(Transition transition) { 1764faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1765199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1766199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase @Override 1767199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void onTransitionPause(Transition transition) { 1768199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1769199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1770199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase @Override 1771199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void onTransitionResume(Transition transition) { 1772199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1773faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1774faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1775199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1776199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Holds information about each animator used when a new transition starts 1777199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * while other transitions are still running to determine whether a running 1778199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation should be canceled or a new animation noop'd. The structure holds 1779199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * information about the state that an animation is going to, to be compared to 1780199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * end state of a new animation. 17810a778eda690a66173733a63622886e888d405c45George Mount * @hide 1782199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 17830a778eda690a66173733a63622886e888d405c45George Mount public static class AnimationInfo { 17840a778eda690a66173733a63622886e888d405c45George Mount public View view; 1785199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase String name; 1786199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues values; 1787cf68aad3164303df59b2a669d186a94533c9c743George Mount WindowId windowId; 1788199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1789cf68aad3164303df59b2a669d186a94533c9c743George Mount AnimationInfo(View view, String name, WindowId windowId, TransitionValues values) { 1790199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.view = view; 1791199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.name = name; 1792199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.values = values; 1793cf68aad3164303df59b2a669d186a94533c9c743George Mount this.windowId = windowId; 1794199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1795199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1796ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1797ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1798ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility class for managing typed ArrayLists efficiently. In particular, this 1799ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * can be useful for lists that we don't expect to be used often (eg, the exclude 1800ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * lists), so we'd like to keep them nulled out by default. This causes the code to 1801ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * become tedious, with constant null checks, code to allocate when necessary, 1802ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * and code to null out the reference when the list is empty. This class encapsulates 1803ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * all of that functionality into simple add()/remove() methods which perform the 1804ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * necessary checks, allocation/null-out as appropriate, and return the 1805ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * resulting list. 1806ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1807ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private static class ArrayListManager { 1808ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1809ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1810ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Add the specified item to the list, returning the resulting list. 1811ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * The returned list can either the be same list passed in or, if that 1812ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list was null, the new list that was created. 1813ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1814ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Note that the list holds unique items; if the item already exists in the 1815ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list, the list is not modified. 1816ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1817ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase static <T> ArrayList<T> add(ArrayList<T> list, T item) { 1818ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list == null) { 1819ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = new ArrayList<T>(); 1820ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1821ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (!list.contains(item)) { 1822ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list.add(item); 1823ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1824ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 1825ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1826ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1827ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1828ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Remove the specified item from the list, returning the resulting list. 1829ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * The returned list can either the be same list passed in or, if that 1830ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list becomes empty as a result of the remove(), the new list was created. 1831ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1832ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase static <T> ArrayList<T> remove(ArrayList<T> list, T item) { 1833ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list != null) { 1834ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list.remove(item); 1835ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list.isEmpty()) { 1836ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = null; 1837ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1838ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1839ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 1840ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1841ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1842ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1843d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1844d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Class to get the epicenter of Transition. Use 1845d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #setEpicenterCallback(android.transition.Transition.EpicenterCallback)} to 1846d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * set the callback used to calculate the epicenter of the Transition. Override 1847d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #getEpicenter()} to return the rectangular region in screen coordinates of 1848d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the epicenter of the transition. 1849d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback) 1850d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1851d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public static abstract class EpicenterCallback { 1852d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1853d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1854d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Implementers must override to return the epicenter of the Transition in screen 1855d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * coordinates. Transitions like {@link android.transition.Explode} depend upon 1856d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * an epicenter for the Transition. In Explode, Views move toward or away from the 1857d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * center of the epicenter Rect along the vector between the epicenter and the center 1858d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * of the View appearing and disappearing. Some Transitions, such as 1859d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Fade} pay no attention to the epicenter. 1860d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 1861d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param transition The transition for which the epicenter applies. 1862d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return The Rect region of the epicenter of <code>transition</code> or null if 1863d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * there is no epicenter. 1864d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1865d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public abstract Rect getEpicenter(Transition transition); 1866d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1867faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase} 1868