Transition.java revision 0a778eda690a66173733a63622886e888d405c45
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; 2208735185f8105710e18ad02297461bec9268e514Chet Haaseimport android.util.ArrayMap; 23c43524f3869cc0d36974fce61986017093f2ecd2Chet Haaseimport android.util.Log; 24faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.util.LongSparseArray; 25faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.util.SparseArray; 26faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.SurfaceView; 27faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.TextureView; 28faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.View; 29faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewGroup; 30faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewOverlay; 31faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.widget.ListView; 32ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haaseimport android.widget.Spinner; 33faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 34faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport java.util.ArrayList; 35d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haaseimport java.util.List; 36faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 37faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/** 38faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * A Transition holds information about animations that will be run on its 39faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * targets during a scene change. Subclasses of this abstract class may 40d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * choreograph several child transitions ({@link TransitionSet} or they may 41faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * perform custom animations themselves. Any Transition has two main jobs: 42faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (1) capture property values, and (2) play animations based on changes to 43faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * captured property values. A custom transition knows what property values 44faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on View objects are of interest to it, and also knows how to animate 45faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes to those values. For example, the {@link Fade} transition tracks 46faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes to visibility-related properties and is able to construct and run 47faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animations that fade items in or out based on changes to those properties. 48faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 49faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>Note: Transitions may not work correctly with either {@link SurfaceView} 50faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * or {@link TextureView}, due to the way that these views are displayed 51faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on the screen. For SurfaceView, the problem is that the view is updated from 52faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * a non-UI thread, so changes to the view due to transitions (such as moving 53faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * and resizing the view) may be out of sync with the display inside those bounds. 54faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * TextureView is more compatible with transitions in general, but some 55d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * specific transitions (such as {@link Fade}) may not be compatible 56faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * with TextureView because they rely on {@link ViewOverlay} functionality, 57faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * which does not currently work with TextureView.</p> 58d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 59d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Transitions can be declared in XML resource files inside the <code>res/transition</code> 60d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * directory. Transition resources consist of a tag name for one of the Transition 61d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * subclasses along with attributes to define some of the attributes of that transition. 62d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition:</p> 63d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 64d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@sample development/samples/ApiDemos/res/transition/changebounds.xml ChangeBounds} 65d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 66d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Note that attributes for the transition are not required, just as they are 67d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * optional when declared in code; Transitions created from XML resources will use 68d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * the same defaults as their code-created equivalents. Here is a slightly more 69d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * elaborate example which declares a {@link TransitionSet} transition with 70d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link ChangeBounds} and {@link Fade} child transitions:</p> 71d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 72d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@sample 73d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * development/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml TransitionSet} 74d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 75d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>In this example, the transitionOrdering attribute is used on the TransitionSet 76d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * object to change from the default {@link TransitionSet#ORDERING_TOGETHER} behavior 77d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * to be {@link TransitionSet#ORDERING_SEQUENTIAL} instead. Also, the {@link Fade} 78d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition uses a fadingMode of {@link Fade#OUT} instead of the default 79d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * out-in behavior. Finally, note the use of the <code>targets</code> sub-tag, which 80d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * takes a set of {@link android.R.styleable#TransitionTarget target} tags, each 81d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of which lists a specific <code>targetId</code> which this transition acts upon. 82d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Use of targets is optional, but can be used to either limit the time spent checking 83d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * attributes on unchanging views, or limiting the types of animations run on specific views. 84d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * In this case, we know that only the <code>grayscaleContainer</code> will be 85d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * disappearing, so we choose to limit the {@link Fade} transition to only that view.</p> 86d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 87d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Further information on XML resource descriptions for transitions can be found for 88d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet}, 89d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link android.R.styleable#TransitionTarget}, and {@link android.R.styleable#Fade}. 90d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 91faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 926ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haasepublic abstract class Transition implements Cloneable { 93faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 94faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private static final String LOG_TAG = "Transition"; 95faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase static final boolean DBG = false; 96faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 97199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private String mName = getClass().getName(); 98199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 99faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long mStartDelay = -1; 100faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long mDuration = -1; 101faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TimeInterpolator mInterpolator = null; 102d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase ArrayList<Integer> mTargetIds = new ArrayList<Integer>(); 103d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase ArrayList<View> mTargets = new ArrayList<View>(); 104ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Integer> mTargetIdExcludes = null; 105ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<View> mTargetExcludes = null; 106ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Class> mTargetTypeExcludes = null; 107ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Integer> mTargetIdChildExcludes = null; 108ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<View> mTargetChildExcludes = null; 109ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Class> mTargetTypeChildExcludes = null; 1106ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private TransitionValuesMaps mStartValues = new TransitionValuesMaps(); 1116ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private TransitionValuesMaps mEndValues = new TransitionValuesMaps(); 112d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase TransitionSet mParent = null; 1136ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 114199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Per-animator information used for later canceling when future transitions overlap 115199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators = 116199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase new ThreadLocal<ArrayMap<Animator, AnimationInfo>>(); 117199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 118d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // Scene Root is set at createAnimator() time in the cloned Transition 1196ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase ViewGroup mSceneRoot = null; 1206ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 121b7a7fc9d233bad507ce893882352618b13647058Chet Haase // Whether removing views from their parent is possible. This is only for views 122b7a7fc9d233bad507ce893882352618b13647058Chet Haase // in the start scene, which are no longer in the view hierarchy. This property 123b7a7fc9d233bad507ce893882352618b13647058Chet Haase // is determined by whether the previous Scene was created from a layout 124b7a7fc9d233bad507ce893882352618b13647058Chet Haase // resource, and thus the views from the exited scene are going away anyway 125b7a7fc9d233bad507ce893882352618b13647058Chet Haase // and can be removed as necessary to achieve a particular effect, such as 126b7a7fc9d233bad507ce893882352618b13647058Chet Haase // removing them from parents to add them to overlays. 127b7a7fc9d233bad507ce893882352618b13647058Chet Haase boolean mCanRemoveViews = false; 128b7a7fc9d233bad507ce893882352618b13647058Chet Haase 129e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // Track all animators in use in case the transition gets canceled and needs to 130e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // cancel running animators 131e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase private ArrayList<Animator> mCurrentAnimators = new ArrayList<Animator>(); 132e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase 133faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Number of per-target instances of this Transition currently running. This count is 134199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // determined by calls to start() and end() 135faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int mNumInstances = 0; 136faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 137199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Whether this transition is currently paused, due to a call to pause() 138199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase boolean mPaused = false; 139c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase 140a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase // Whether this transition has ended. Used to avoid pause/resume on transitions 141a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase // that have completed 142a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase private boolean mEnded = false; 143a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase 144c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase // The set of listeners to be sent transition lifecycle events. 145faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> mListeners = null; 146faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 147d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // The set of animators collected from calls to createAnimator(), 148d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // to be run in runAnimators() 149199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayList<Animator> mAnimators = new ArrayList<Animator>(); 150c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase 151faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 152faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Constructs a Transition object with no target objects. A transition with 153faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * no targets defaults to running on all target objects in the scene hierarchy 154d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * (if the transition is not contained in a TransitionSet), or all target 155d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * objects passed down from its parent (if it is in a TransitionSet). 156faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 157faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public Transition() {} 158faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 159faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 160faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the duration of this transition. By default, there is no duration 161faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (indicated by a negative number), which means that the Animator created by 162faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition will have its own specified duration. If the duration of a 163faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that duration will override the Animator duration. 164faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 165faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param duration The length of the animation, in milliseconds. 166faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return This transition object. 167d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_duration 168faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 169faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public Transition setDuration(long duration) { 170faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mDuration = duration; 171faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 172faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 173faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 174199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 175199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the duration set on this transition. If no duration has been set, 176199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be negative, indicating that resulting animators will 177199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own durations. 178199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 179d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The duration set on this transition, in milliseconds, if one has been 180d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * set, otherwise returns a negative number. 181199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 182faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public long getDuration() { 183faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mDuration; 184faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 185faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 186faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 187faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the startDelay of this transition. By default, there is no delay 188faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (indicated by a negative number), which means that the Animator created by 189faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition will have its own specified startDelay. If the delay of a 190faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that delay will override the Animator delay. 191faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 192faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param startDelay The length of the delay, in milliseconds. 193d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 194d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_startDelay 195faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 196d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition setStartDelay(long startDelay) { 197faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mStartDelay = startDelay; 198d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 199faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 200faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 201199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 202199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the startDelay set on this transition. If no startDelay has been set, 203199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be negative, indicating that resulting animators will 204199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own startDelays. 205199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 206d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The startDelay set on this transition, in milliseconds, if one has 207d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * been set, otherwise returns a negative number. 208199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 209faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public long getStartDelay() { 210faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mStartDelay; 211faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 212faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 213faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 214faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the interpolator of this transition. By default, the interpolator 215faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is null, which means that the Animator created by the transition 216faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will have its own specified interpolator. If the interpolator of a 217faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that interpolator will override the Animator interpolator. 218faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 219faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param interpolator The time interpolator used by the transition 220d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 221d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_interpolator 222faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 223d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition setInterpolator(TimeInterpolator interpolator) { 224faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mInterpolator = interpolator; 225d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 226faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 227faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 228199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 229199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the interpolator set on this transition. If no interpolator has been set, 230199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be null, indicating that resulting animators will 231199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own interpolators. 232199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 233199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return The interpolator set on this transition, if one has been set, otherwise 234199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * returns null. 235199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 236faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public TimeInterpolator getInterpolator() { 237faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mInterpolator; 238faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 239faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 240faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 241199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the set of property names used stored in the {@link TransitionValues} 242d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * object passed into {@link #captureStartValues(TransitionValues)} that 243199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * this transition cares about for the purposes of canceling overlapping animations. 244199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * When any transition is started on a given scene root, all transitions 245199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * currently running on that same scene root are checked to see whether the 246199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * properties on which they based their animations agree with the end values of 247199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the same properties in the new transition. If the end values are not equal, 248199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * then the old animation is canceled since the new transition will start a new 249199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation to these new values. If the values are equal, the old animation is 250199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * allowed to continue and no new animation is started for that transition. 251199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 252199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * <p>A transition does not need to override this method. However, not doing so 253199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * will mean that the cancellation logic outlined in the previous paragraph 254199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * will be skipped for that transition, possibly leading to artifacts as 255199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * old transitions and new transitions on the same targets run in parallel, 256199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animating views toward potentially different end values.</p> 257199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 258199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return An array of property names as described in the class documentation for 259199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * {@link TransitionValues}. The default implementation returns <code>null</code>. 260199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 261199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public String[] getTransitionProperties() { 262199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return null; 263199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 264199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 265199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 266d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * This method creates an animation that will be run for this transition 267d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * given the information in the startValues and endValues structures captured 268d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * earlier for the start and end scenes. Subclasses of Transition should override 269d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * this method. The method should only be called by the transition system; it is 270d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * not intended to be called from external classes. 271d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 272d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>This method is called by the transition's parent (all the way up to the 273faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * topmost Transition in the hierarchy) with the sceneRoot and start/end 2742ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * values that the transition may need to set up initial target values 2752ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * and construct an appropriate animation. For example, if an overall 276d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Transition is a {@link TransitionSet} consisting of several 277faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * child transitions in sequence, then some of the child transitions may 278faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * want to set initial values on target views prior to the overall 2792ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * Transition commencing, to put them in an appropriate state for the 280faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * delay between that start and the child Transition start time. For 281faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * example, a transition that fades an item in may wish to set the starting 282faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * alpha value to 0, to avoid it blinking in prior to the transition 283faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * actually starting the animation. This is necessary because the scene 284faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * change that triggers the Transition will automatically set the end-scene 285faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on all target views, so a Transition that wants to animate from a 286d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * different value should set that value prior to returning from this method.</p> 287faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 288faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>Additionally, a Transition can perform logic to determine whether 289faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition needs to run on the given target and start/end values. 290faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * For example, a transition that resizes objects on the screen may wish 291faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * to avoid running for views which are not present in either the start 292d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * or end scenes.</p> 2932ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * 2942ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <p>If there is an animator created and returned from this method, the 2952ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * transition mechanism will apply any applicable duration, startDelay, 2962ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * and interpolator to that animation and start it. A return value of 2972ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <code>null</code> indicates that no animation should run. The default 2982ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * implementation returns null.</p> 299faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 300faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>The method is called for every applicable target object, which is 301faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * stored in the {@link TransitionValues#view} field.</p> 302faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 303d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 304d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param sceneRoot The root of the transition hierarchy. 305d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param startValues The values for a specific target in the start scene. 306d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param endValues The values for the target in the end scene. 307d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return A Animator to be started at the appropriate time in the 308d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * overall transition for this scene change. A null value means no animation 309d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should be run. 310faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 311d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, 312faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues endValues) { 3132ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase return null; 314faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 315faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 316faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 317d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * This method, essentially a wrapper around all calls to createAnimator for all 318d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * possible target views, is called with the entire set of start/end 319faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * values. The implementation in Transition iterates through these lists 320d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)} 321faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * with each set of start/end values on this transition. The 322d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet subclass overrides this method and delegates it to 3232ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * each of its children in succession. 324faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 325faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 326faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 327d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues, 3286ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValuesMaps endValues) { 329c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 330d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Log.d(LOG_TAG, "createAnimators() for " + this); 331c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 3326ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase ArrayMap<View, TransitionValues> endCopy = 3336ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase new ArrayMap<View, TransitionValues>(endValues.viewValues); 334faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase SparseArray<TransitionValues> endIdCopy = 3356ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase new SparseArray<TransitionValues>(endValues.idValues.size()); 3366ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < endValues.idValues.size(); ++i) { 3376ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int id = endValues.idValues.keyAt(i); 3386ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase endIdCopy.put(id, endValues.idValues.valueAt(i)); 339faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 340faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase LongSparseArray<TransitionValues> endItemIdCopy = 3416ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase new LongSparseArray<TransitionValues>(endValues.itemIdValues.size()); 3426ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < endValues.itemIdValues.size(); ++i) { 3436ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase long id = endValues.itemIdValues.keyAt(i); 3446ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase endItemIdCopy.put(id, endValues.itemIdValues.valueAt(i)); 345faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 346faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Walk through the start values, playing everything we find 347faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Remove from the end set as we go 348faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionValues> startValuesList = new ArrayList<TransitionValues>(); 349faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionValues> endValuesList = new ArrayList<TransitionValues>(); 3506ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (View view : startValues.viewValues.keySet()) { 351faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues start = null; 352faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = null; 353faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase boolean isInListView = false; 354faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view.getParent() instanceof ListView) { 355faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase isInListView = true; 356faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 357faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (!isInListView) { 358faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int id = view.getId(); 3596ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase start = startValues.viewValues.get(view) != null ? 3606ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase startValues.viewValues.get(view) : startValues.idValues.get(id); 3616ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (endValues.viewValues.get(view) != null) { 3626ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase end = endValues.viewValues.get(view); 363faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endCopy.remove(view); 364c46181a963be736186ae29101625a05b5c1f0ba8Chet Haase } else if (id != View.NO_ID) { 3656ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase end = endValues.idValues.get(id); 366faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase View removeView = null; 367faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (View viewToRemove : endCopy.keySet()) { 368faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (viewToRemove.getId() == id) { 369faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase removeView = viewToRemove; 370faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 371faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 372faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (removeView != null) { 373faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endCopy.remove(removeView); 374faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 375faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 376faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endIdCopy.remove(id); 377faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isValidTarget(view, id)) { 378faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 379faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 380faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 381faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 382faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ListView parent = (ListView) view.getParent(); 383faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (parent.getAdapter().hasStableIds()) { 384faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int position = parent.getPositionForView(view); 385faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long itemId = parent.getItemIdAtPosition(position); 3866ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase start = startValues.itemIdValues.get(itemId); 387faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endItemIdCopy.remove(itemId); 388faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // TODO: deal with targetIDs for itemIDs for ListView items 389faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 390faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 391faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 392faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 393faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 3946ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int startItemIdCopySize = startValues.itemIdValues.size(); 395faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < startItemIdCopySize; ++i) { 3966ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase long id = startValues.itemIdValues.keyAt(i); 397faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isValidTarget(null, id)) { 3986ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues start = startValues.itemIdValues.get(id); 3996ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues end = endValues.itemIdValues.get(id); 400faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endItemIdCopy.remove(id); 401faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 402faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 403faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 404faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 405faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Now walk through the remains of the end set 406faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (View view : endCopy.keySet()) { 407faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int id = view.getId(); 408faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isValidTarget(view, id)) { 4096ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues start = startValues.viewValues.get(view) != null ? 4106ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase startValues.viewValues.get(view) : startValues.idValues.get(id); 411faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endCopy.get(view); 412faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endIdCopy.remove(id); 413faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 414faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 415faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 416faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 417faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int endIdCopySize = endIdCopy.size(); 418faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < endIdCopySize; ++i) { 419faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int id = endIdCopy.keyAt(i); 420faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isValidTarget(null, id)) { 4216ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues start = startValues.idValues.get(id); 422faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endIdCopy.get(id); 423faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 424faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 425faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 426faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 427faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int endItemIdCopySize = endItemIdCopy.size(); 428faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < endItemIdCopySize; ++i) { 429faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long id = endItemIdCopy.keyAt(i); 430faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // TODO: Deal with targetIDs and itemIDs 4316ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues start = startValues.itemIdValues.get(id); 432faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endItemIdCopy.get(id); 433faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase startValuesList.add(start); 434faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase endValuesList.add(end); 435faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 436199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 437faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < startValuesList.size(); ++i) { 438faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues start = startValuesList.get(i); 439faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endValuesList.get(i); 440c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase // Only bother trying to animate with values that differ between start/end 441c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (start != null || end != null) { 442c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (start == null || !start.equals(end)) { 443c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 444c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase View view = (end != null) ? end.view : start.view; 445c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Log.d(LOG_TAG, " differing start/end values for view " + 446c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase view); 447c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (start == null || end == null) { 448ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase Log.d(LOG_TAG, " " + ((start == null) ? 449ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase "start null, end non-null" : "start non-null, end null")); 450c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } else { 451c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase for (String key : start.values.keySet()) { 452c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Object startValue = start.values.get(key); 453c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Object endValue = end.values.get(key); 454c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (startValue != endValue && !startValue.equals(endValue)) { 455c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Log.d(LOG_TAG, " " + key + ": start(" + startValue + 456c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase "), end(" + endValue +")"); 457c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 458c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 459c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 460c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 461c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase // TODO: what to do about targetIds and itemIds? 462d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Animator animator = createAnimator(sceneRoot, start, end); 463c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (animator != null) { 464199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Save animation info for future cancellation purposes 465199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase View view = null; 466199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues infoValues = null; 467199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (end != null) { 468199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase view = end.view; 469199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase String[] properties = getTransitionProperties(); 470199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (view != null && properties != null && properties.length > 0) { 471199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase infoValues = new TransitionValues(); 472199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase infoValues.view = view; 473199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues newValues = endValues.viewValues.get(view); 474199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (newValues != null) { 475199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (int j = 0; j < properties.length; ++j) { 476199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase infoValues.values.put(properties[j], 477199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase newValues.values.get(properties[j])); 478199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 479199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 480199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase int numExistingAnims = runningAnimators.size(); 481199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (int j = 0; j < numExistingAnims; ++j) { 482199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Animator anim = runningAnimators.keyAt(j); 483199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase AnimationInfo info = runningAnimators.get(anim); 484199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (info.values != null && info.view == view && 485199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ((info.name == null && getName() == null) || 486199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase info.name.equals(getName()))) { 487199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (info.values.equals(infoValues)) { 488199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Favor the old animator 489199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase animator = null; 490199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase break; 491199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 492199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 493199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 494199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 495199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } else { 496199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase view = (start != null) ? start.view : null; 497199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 498199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (animator != null) { 499199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase AnimationInfo info = new AnimationInfo(view, getName(), infoValues); 500199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.put(animator, info); 501199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mAnimators.add(animator); 502199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 503c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 504c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 505faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 506faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 507faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 508faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 509faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 510faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Internal utility method for checking whether a given view/id 511faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is valid for this transition, where "valid" means that either 512faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition has no target/targetId list (the default, in which 513faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * cause the transition should act on all views in the hiearchy), or 514faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the given view is in the target list or the view id is in the 515faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * targetId list. If the target parameter is null, then the target list 516faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is not checked (this is in the case of ListView items, where the 517faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * views are ignored and only the ids are used). 518faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 519faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase boolean isValidTarget(View target, long targetId) { 520ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdExcludes != null && mTargetIdExcludes.contains(targetId)) { 521ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 522ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 523ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetExcludes != null && mTargetExcludes.contains(target)) { 524ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 525ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 526ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes != null && target != null) { 527ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeExcludes.size(); 528ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 529ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase Class type = mTargetTypeExcludes.get(i); 530ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (type.isInstance(target)) { 531ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 532ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 533ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 534ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 535d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() == 0 && mTargets.size() == 0) { 536faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 537faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 538d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0) { 539d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargetIds.size(); ++i) { 540d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.get(i) == targetId) { 541faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 542faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 543faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 544faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 545d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (target != null && mTargets.size() > 0) { 546d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargets.size(); ++i) { 547d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargets.get(i) == target) { 548faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 549faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 550faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 551faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 552faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return false; 553faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 554faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 5550a778eda690a66173733a63622886e888d405c45George Mount /** @hide */ 5560a778eda690a66173733a63622886e888d405c45George Mount public static ArrayMap<Animator, AnimationInfo> getRunningAnimators() { 557199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get(); 558199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (runningAnimators == null) { 559199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators = new ArrayMap<Animator, AnimationInfo>(); 560199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase sRunningAnimators.set(runningAnimators); 561199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 562199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return runningAnimators; 563199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 564199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 565faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 5662ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * This is called internally once all animations have been set up by the 5672ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * transition hierarchy. \ 568faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 569faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 570faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 571d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase protected void runAnimators() { 572199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 573d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Log.d(LOG_TAG, "runAnimators() on " + this); 574199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 575199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase start(); 576199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 577d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // Now start every Animator that was previously created for this transition 578199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (Animator anim : mAnimators) { 579c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 580c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Log.d(LOG_TAG, " anim: " + anim); 581c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 582199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (runningAnimators.containsKey(anim)) { 583199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase start(); 584199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runAnimator(anim, runningAnimators); 585199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 586faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 587199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mAnimators.clear(); 588199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 589faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 590faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 591199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private void runAnimator(Animator animator, 592199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase final ArrayMap<Animator, AnimationInfo> runningAnimators) { 593e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase if (animator != null) { 594e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // TODO: could be a single listener instance for all of them since it uses the param 595e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animator.addListener(new AnimatorListenerAdapter() { 596e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase @Override 597e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase public void onAnimationStart(Animator animation) { 598e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase mCurrentAnimators.add(animation); 599e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 600e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase @Override 601e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase public void onAnimationEnd(Animator animation) { 602199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.remove(animation); 603e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase mCurrentAnimators.remove(animation); 604e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 605e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase }); 606e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animate(animator); 607e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 608e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 609e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase 610faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 611d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Captures the values in the start scene for the properties that this 612d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition monitors. These values are then passed as the startValues 613d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * structure in a later call to 614d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 615d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The main concern for an implementation is what the 616d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * properties are that the transition cares about and what the values are 617d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * for all of those properties. The start and end values will be compared 618d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * later during the 619d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)} 620d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * method to determine what, if any, animations, should be run. 621d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 622d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Subclasses must implement this method. The method should only be called by the 623d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition system; it is not intended to be called from external classes.</p> 624d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 625d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param transitionValues The holder for any values that the Transition 626d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * wishes to store. Values are stored in the <code>values</code> field 627d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of this TransitionValues object and are keyed from 628d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * a String value. For example, to store a view's rotation value, 629d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * a transition might call 630d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionValues.values.put("appname:transitionname:rotation", 631d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * view.getRotation())</code>. The target view will already be stored in 632d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * the transitionValues structure when this method is called. 633d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 634d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #captureEndValues(TransitionValues) 635d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 636d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 637d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public abstract void captureStartValues(TransitionValues transitionValues); 638d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 639d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 640d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Captures the values in the end scene for the properties that this 641d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition monitors. These values are then passed as the endValues 642d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * structure in a later call to 643d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 644d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The main concern for an implementation is what the 645faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * properties are that the transition cares about and what the values are 646faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * for all of those properties. The start and end values will be compared 6472ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * later during the 648d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)} 6492ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * method to determine what, if any, animations, should be run. 650faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 651d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Subclasses must implement this method. The method should only be called by the 652d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition system; it is not intended to be called from external classes.</p> 653d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 6542ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * @param transitionValues The holder for any values that the Transition 6552ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * wishes to store. Values are stored in the <code>values</code> field 6562ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * of this TransitionValues object and are keyed from 6572ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * a String value. For example, to store a view's rotation value, 6582ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * a transition might call 6592ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <code>transitionValues.values.put("appname:transitionname:rotation", 6602ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * view.getRotation())</code>. The target view will already be stored in 6612ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * the transitionValues structure when this method is called. 662d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 663d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #captureStartValues(TransitionValues) 664d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 665faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 666d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public abstract void captureEndValues(TransitionValues transitionValues); 667faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 668faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 669d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Adds the id of a target view that this Transition is interested in 670faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animating. By default, there are no targetIds, and a Transition will 671faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listen for changes on every view in the hierarchy below the sceneRoot 672d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of the Scene being transitioned into. Setting targetIds constrains 673faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition to only listen for, and act on, views with these IDs. 674faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Views with different IDs, or no IDs whatsoever, will be ignored. 675faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 676d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Note that using ids to specify targets implies that ids should be unique 677d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * within the view hierarchy underneat the scene root.</p> 678d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 679faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @see View#getId() 680d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param targetId The id of a target view, must be a positive number. 681d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition to which the targetId is added. 682d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Returning the same object makes it easier to chain calls during 683d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * construction, such as 684ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <code>transitionSet.addTransitions(new Fade()).addTarget(someId);</code> 685d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 686ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition addTarget(int targetId) { 687d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (targetId > 0) { 688d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargetIds.add(targetId); 689d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 690d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 691d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 692d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 693d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 694d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Removes the given targetId from the list of ids that this Transition 695d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * is interested in animating. 696d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 697d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param targetId The id of a target view, must be a positive number. 698d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition from which the targetId is removed. 699faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returning the same object makes it easier to chain calls during 700faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * construction, such as 701d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code> 702faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 703ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition removeTarget(int targetId) { 704d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (targetId > 0) { 705d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargetIds.remove(targetId); 706d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 707faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 708faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 709faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 710faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 711ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given id to the list of target ids to exclude from this 712ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 713ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should be added to or removed from the excluded list. 714ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 715ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 716ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 717ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 718ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 719ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 720ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 721ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 722ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 723ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 724ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 725ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 726ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param targetId The id of a target to ignore when running this transition. 727ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 728ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 729ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 730ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 731ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(int targetId, boolean exclude) { 732ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetIdExcludes = excludeId(mTargetIdExcludes, targetId, exclude); 733ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 734ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 735ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 736ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 737ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the children of the given id to the list of targets to exclude 738ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * from this transition. The <code>exclude</code> parameter specifies whether 739ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the children of the target should be added to or removed from the excluded list. 740ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Excluding children in this way provides a simple mechanism for excluding all 741ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * children of specific targets, rather than individually excluding each 742ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * child individually. 743ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 744ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 745ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 746ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 747ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 748ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 749ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 750ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 751ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 752ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 753ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 754ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 755ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param targetId The id of a target whose children should be ignored when running 756ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * this transition. 757ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 758ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded-child targets. 759ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 760ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 761ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(int targetId, boolean exclude) { 762ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetIdChildExcludes = excludeId(mTargetIdChildExcludes, targetId, exclude); 763ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 764ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 765ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 766ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 767ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility method to manage the boilerplate code that is the same whether we 768ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * are excluding targets or their children. 769ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 770ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private ArrayList<Integer> excludeId(ArrayList<Integer> list, int targetId, boolean exclude) { 771ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (targetId > 0) { 772ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (exclude) { 773ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.add(list, targetId); 774ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } else { 775ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.remove(list, targetId); 776ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 777ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 778ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 779ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 780ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 781ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 782ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given target to the list of targets to exclude from this 783ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 784ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should be added to or removed from the excluded list. 785ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 786ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 787ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 788ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 789ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 790ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 791ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 792ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 793ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 794ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 795ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 796ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 797ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param target The target to ignore when running this transition. 798ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 799ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 800ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 801ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 802ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(View target, boolean exclude) { 803ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetExcludes = excludeView(mTargetExcludes, target, exclude); 804ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 805ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 806ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 807ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 808ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the children of given target to the list of target children 809ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * to exclude from this transition. The <code>exclude</code> parameter specifies 810ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * whether the target should be added to or removed from the excluded list. 811ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 812ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 813ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 814ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 815ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 816ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 817ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 818ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 819ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 820ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 821ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 822ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 823ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param target The target to ignore when running this transition. 824ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 825ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 826ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 827ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 828ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(View target, boolean exclude) { 829ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetChildExcludes = excludeView(mTargetChildExcludes, target, exclude); 830ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 831ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 832ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 833ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 834ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility method to manage the boilerplate code that is the same whether we 835ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * are excluding targets or their children. 836ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 837ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private ArrayList<View> excludeView(ArrayList<View> list, View target, boolean exclude) { 838ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (target != null) { 839ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (exclude) { 840ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.add(list, target); 841ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } else { 842ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.remove(list, target); 843ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 844ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 845ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 846ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 847ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 848ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 849ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given type to the list of types to exclude from this 850ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 851ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * type should be added to or removed from the excluded list. 852ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 853ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 854ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 855ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 856ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 857ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 858ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 859ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 860ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 861ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 862ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 863ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 864ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param type The type to ignore when running this transition. 865ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target type to or remove it from the 866ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded target types. 867ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 868ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 869ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(Class type, boolean exclude) { 870ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetTypeExcludes = excludeType(mTargetTypeExcludes, type, exclude); 871ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 872ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 873ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 874ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 875ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given type to the list of types whose children should 876ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * be excluded from this transition. The <code>exclude</code> parameter 877ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * specifies whether the target type should be added to or removed from 878ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the excluded list. 879ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 880ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 881ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 882ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 883ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 884ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 885ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 886ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 887ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 888ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 889ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 890ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 891ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param type The type to ignore when running this transition. 892ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target type to or remove it from the 893ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded target types. 894ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 895ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 896ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(Class type, boolean exclude) { 897ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mTargetTypeChildExcludes = excludeType(mTargetTypeChildExcludes, type, exclude); 898ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 899ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 900ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 901ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 902ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility method to manage the boilerplate code that is the same whether we 903ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * are excluding targets or their children. 904ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 905ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private ArrayList<Class> excludeType(ArrayList<Class> list, Class type, boolean exclude) { 906ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (type != null) { 907ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (exclude) { 908ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.add(list, type); 909ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } else { 910ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.remove(list, type); 911ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 912ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 913ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 914ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 915ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 916ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 917faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the target view instances that this Transition is interested in 918faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animating. By default, there are no targets, and a Transition will 919faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listen for changes on every view in the hierarchy below the sceneRoot 920faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * of the Scene being transitioned into. Setting targets constrains 921faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition to only listen for, and act on, these views. 922faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * All other views will be ignored. 923faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 924ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>The target list is like the {@link #addTarget(int) targetId} 925faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * list except this list specifies the actual View instances, not the ids 926faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * of the views. This is an important distinction when scene changes involve 927faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * view hierarchies which have been inflated separately; different views may 928faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * share the same id but not actually be the same instance. If the transition 929ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should treat those views as the same, then {@link #addTarget(int)} should be used 930d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve 931faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes all within the same view hierarchy, among views which do not 932d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * necessarily have ids set on them, then the target list of views may be more 933faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * convenient.</p> 934faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 935ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #addTarget(int) 936d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param target A View on which the Transition will act, must be non-null. 937d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition to which the target is added. 938d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Returning the same object makes it easier to chain calls during 939d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * construction, such as 940d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code> 941d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 942d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition addTarget(View target) { 943d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargets.add(target); 944d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 945d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 946d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 947d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 948d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Removes the given target from the list of targets that this Transition 949d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * is interested in animating. 950d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 951d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param target The target view, must be non-null. 952d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return Transition The Transition from which the target is removed. 953faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returning the same object makes it easier to chain calls during 954faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * construction, such as 955d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code> 956faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 957d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition removeTarget(View target) { 958d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (target != null) { 959d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargets.remove(target); 960d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 961faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 962faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 963faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 964faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 965faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returns the array of target IDs that this transition limits itself to 966faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * tracking and animating. If the array is null for both this method and 967faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * {@link #getTargets()}, then this transition is 968faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * not limited to specific views, and will handle changes to any views 969faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * in the hierarchy of a scene change. 970faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 971faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return the list of target IDs 972faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 973d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public List<Integer> getTargetIds() { 974faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mTargetIds; 975faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 976faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 977faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 978faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returns the array of target views that this transition limits itself to 979faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * tracking and animating. If the array is null for both this method and 980faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * {@link #getTargetIds()}, then this transition is 981faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * not limited to specific views, and will handle changes to any views 982faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * in the hierarchy of a scene change. 983faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 984faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return the list of target views 985faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 986d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public List<View> getTargets() { 987faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mTargets; 988faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 989faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 990faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 991faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Recursive method that captures values for the given view and the 992faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * hierarchy underneath it. 993faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param sceneRoot The root of the view hierarchy being captured 994faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param start true if this capture is happening before the scene change, 995faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * false otherwise 996faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 997faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void captureValues(ViewGroup sceneRoot, boolean start) { 998df32aa87150768795816852c6393306893467ecaChet Haase clearValues(start); 999d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0 || mTargets.size() > 0) { 1000d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0) { 1001d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargetIds.size(); ++i) { 1002d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase int id = mTargetIds.get(i); 1003faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase View view = sceneRoot.findViewById(id); 1004faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view != null) { 1005faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues values = new TransitionValues(); 1006faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase values.view = view; 1007d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (start) { 1008d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureStartValues(values); 1009d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } else { 1010d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureEndValues(values); 1011d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 1012faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (start) { 10136ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mStartValues.viewValues.put(view, values); 1014867a86613d4152a93423300f83597300e6ebeebeChet Haase if (id >= 0) { 10156ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mStartValues.idValues.put(id, values); 1016867a86613d4152a93423300f83597300e6ebeebeChet Haase } 1017faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 10186ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mEndValues.viewValues.put(view, values); 1019867a86613d4152a93423300f83597300e6ebeebeChet Haase if (id >= 0) { 10206ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mEndValues.idValues.put(id, values); 1021867a86613d4152a93423300f83597300e6ebeebeChet Haase } 1022faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1023faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1024faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1025faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1026d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargets.size() > 0) { 1027d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargets.size(); ++i) { 1028d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase View view = mTargets.get(i); 1029faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view != null) { 1030faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues values = new TransitionValues(); 1031faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase values.view = view; 1032d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (start) { 1033d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureStartValues(values); 1034d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } else { 1035d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase captureEndValues(values); 1036d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 1037faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (start) { 10386ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mStartValues.viewValues.put(view, values); 1039faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 10406ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mEndValues.viewValues.put(view, values); 1041faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1042faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1043faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1044faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1045faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1046faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase captureHierarchy(sceneRoot, start); 1047faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1048faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1049faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1050faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1051df32aa87150768795816852c6393306893467ecaChet Haase * Clear valuesMaps for specified start/end state 1052df32aa87150768795816852c6393306893467ecaChet Haase * 1053df32aa87150768795816852c6393306893467ecaChet Haase * @param start true if the start values should be cleared, false otherwise 1054df32aa87150768795816852c6393306893467ecaChet Haase */ 1055df32aa87150768795816852c6393306893467ecaChet Haase void clearValues(boolean start) { 1056df32aa87150768795816852c6393306893467ecaChet Haase if (start) { 1057df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.viewValues.clear(); 1058df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.idValues.clear(); 1059df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.itemIdValues.clear(); 1060df32aa87150768795816852c6393306893467ecaChet Haase } else { 1061df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.viewValues.clear(); 1062df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.idValues.clear(); 1063df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.itemIdValues.clear(); 1064df32aa87150768795816852c6393306893467ecaChet Haase } 1065df32aa87150768795816852c6393306893467ecaChet Haase } 1066df32aa87150768795816852c6393306893467ecaChet Haase 1067df32aa87150768795816852c6393306893467ecaChet Haase /** 1068faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Recursive method which captures values for an entire view hierarchy, 1069faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * starting at some root view. Transitions without targetIDs will use this 1070faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * method to capture values for all possible views. 1071faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1072faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param view The view for which to capture values. Children of this View 1073faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will also be captured, recursively down to the leaf nodes. 1074faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param start true if values are being captured in the start scene, false 1075faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * otherwise. 1076faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1077faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private void captureHierarchy(View view, boolean start) { 1078faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view == null) { 1079faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return; 1080faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 10810a778eda690a66173733a63622886e888d405c45George Mount if (!isValidTarget(view, view.getId())) { 10820a778eda690a66173733a63622886e888d405c45George Mount return; 10830a778eda690a66173733a63622886e888d405c45George Mount } 1084faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase boolean isListViewItem = false; 1085faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view.getParent() instanceof ListView) { 1086faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase isListViewItem = true; 1087faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1088faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (isListViewItem && !((ListView) view.getParent()).getAdapter().hasStableIds()) { 1089faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // ignore listview children unless we can track them with stable IDs 1090faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return; 1091faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1092ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int id = View.NO_ID; 1093ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase long itemId = View.NO_ID; 1094faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (!isListViewItem) { 1095faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase id = view.getId(); 1096faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1097faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ListView listview = (ListView) view.getParent(); 1098faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int position = listview.getPositionForView(view); 1099ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase itemId = listview.getItemIdAtPosition(position); 1100faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase view.setHasTransientState(true); 1101faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1102ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdExcludes != null && mTargetIdExcludes.contains(id)) { 1103ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1104ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1105ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetExcludes != null && mTargetExcludes.contains(view)) { 1106ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1107ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1108ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes != null && view != null) { 1109ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeExcludes.size(); 1110ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 1111ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes.get(i).isInstance(view)) { 1112ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1113ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1114ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1115ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1116faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues values = new TransitionValues(); 1117faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase values.view = view; 1118d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase if (start) { 1119d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase captureStartValues(values); 1120d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } else { 1121d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase captureEndValues(values); 1122d8d7c38533d20062166e5e7ef89b80ff9dbd8903Chet Haase } 1123faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (start) { 1124faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (!isListViewItem) { 11256ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mStartValues.viewValues.put(view, values); 1126867a86613d4152a93423300f83597300e6ebeebeChet Haase if (id >= 0) { 11276ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mStartValues.idValues.put((int) id, values); 1128867a86613d4152a93423300f83597300e6ebeebeChet Haase } 1129faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1130ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mStartValues.itemIdValues.put(itemId, values); 1131faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1132faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1133faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (!isListViewItem) { 11346ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mEndValues.viewValues.put(view, values); 1135867a86613d4152a93423300f83597300e6ebeebeChet Haase if (id >= 0) { 11366ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mEndValues.idValues.put((int) id, values); 1137867a86613d4152a93423300f83597300e6ebeebeChet Haase } 1138faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1139ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase mEndValues.itemIdValues.put(itemId, values); 1140faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1141faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1142faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view instanceof ViewGroup) { 1143ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase // Don't traverse child hierarchy if there are any child-excludes on this view 1144ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdChildExcludes != null && mTargetIdChildExcludes.contains(id)) { 1145ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1146ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1147ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetChildExcludes != null && mTargetChildExcludes.contains(view)) { 1148ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1149ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1150ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeChildExcludes != null && view != null) { 1151ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeChildExcludes.size(); 1152ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 1153ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeChildExcludes.get(i).isInstance(view)) { 1154ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1155ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1156ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1157ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1158faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ViewGroup parent = (ViewGroup) view; 1159faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < parent.getChildCount(); ++i) { 1160faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase captureHierarchy(parent.getChildAt(i), start); 1161faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1162faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1163faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1164faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1165faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 11666ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * This method can be called by transitions to get the TransitionValues for 11676ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * any particular view during the transition-playing process. This might be 11686ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * necessary, for example, to query the before/after state of related views 11696ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * for a given transition. 11706ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase */ 1171d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public TransitionValues getTransitionValues(View view, boolean start) { 11726ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (mParent != null) { 11736ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return mParent.getTransitionValues(view, start); 11746ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 11756ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValuesMaps valuesMaps = start ? mStartValues : mEndValues; 11766ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues values = valuesMaps.viewValues.get(view); 11776ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (values == null) { 11786ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int id = view.getId(); 11796ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (id >= 0) { 11806ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase values = valuesMaps.idValues.get(id); 11816ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 11826ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (values == null && view.getParent() instanceof ListView) { 11836ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase ListView listview = (ListView) view.getParent(); 11846ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase int position = listview.getPositionForView(view); 11856ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase long itemId = listview.getItemIdAtPosition(position); 11866ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase values = valuesMaps.itemIdValues.get(itemId); 11876ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 11886ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase // TODO: Doesn't handle the case where a view was parented to a 11896ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase // ListView (with an itemId), but no longer is 11906ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 11916ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return values; 11926ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 11936ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 11946ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase /** 1195199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Pauses this transition, sending out calls to {@link 1196199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * TransitionListener#onTransitionPause(Transition)} to all listeners 1197199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * and pausing all running animators started by this transition. 1198199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1199199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @hide 1200199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1201199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void pause() { 1202a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (!mEnded) { 1203a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1204a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numOldAnims = runningAnimators.size(); 1205a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1206a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase Animator anim = runningAnimators.keyAt(i); 1207a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase anim.pause(); 1208a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1209a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (mListeners != null && mListeners.size() > 0) { 1210a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayList<TransitionListener> tmpListeners = 1211a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1212a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numListeners = tmpListeners.size(); 1213a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = 0; i < numListeners; ++i) { 1214a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase tmpListeners.get(i).onTransitionPause(this); 1215a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1216199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1217a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mPaused = true; 1218199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1219199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1220199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1221199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1222199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Resumes this transition, sending out calls to {@link 1223199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * TransitionListener#onTransitionPause(Transition)} to all listeners 1224199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * and pausing all running animators started by this transition. 1225199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1226199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @hide 1227199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1228199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void resume() { 1229199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (mPaused) { 1230a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (!mEnded) { 1231a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1232a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numOldAnims = runningAnimators.size(); 1233a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1234a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase Animator anim = runningAnimators.keyAt(i); 1235a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase anim.resume(); 1236a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1237a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (mListeners != null && mListeners.size() > 0) { 1238a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayList<TransitionListener> tmpListeners = 1239a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1240a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numListeners = tmpListeners.size(); 1241a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = 0; i < numListeners; ++i) { 1242a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase tmpListeners.get(i).onTransitionResume(this); 1243a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1244199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1245199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1246199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mPaused = false; 1247199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1248199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1249199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1250199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1251faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Called by TransitionManager to play the transition. This calls 1252d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimators() to set things up and create all of the animations and then 12532ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * runAnimations() to actually start the animations. 1254faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 12556ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase void playTransition(ViewGroup sceneRoot) { 1256199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1257199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase int numOldAnims = runningAnimators.size(); 1258199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1259199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Animator anim = runningAnimators.keyAt(i); 1260199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (anim != null) { 1261199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase AnimationInfo oldInfo = runningAnimators.get(anim); 126258ad12208afcf9fdce735dead8449c4db375344dChet Haase if (oldInfo != null && oldInfo.view != null && 126358ad12208afcf9fdce735dead8449c4db375344dChet Haase oldInfo.view.getContext() == sceneRoot.getContext()) { 1264199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase boolean cancel = false; 1265199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues oldValues = oldInfo.values; 1266199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase View oldView = oldInfo.view; 1267199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues newValues = mEndValues.viewValues != null ? 1268199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mEndValues.viewValues.get(oldView) : null; 126923c61f6bc57a611d97d333bce0d8fe00ab81af4cChet Haase if (newValues == null) { 127023c61f6bc57a611d97d333bce0d8fe00ab81af4cChet Haase newValues = mEndValues.idValues.get(oldView.getId()); 127123c61f6bc57a611d97d333bce0d8fe00ab81af4cChet Haase } 1272af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (oldValues != null) { 1273af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase // if oldValues null, then transition didn't care to stash values, 1274af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase // and won't get canceled 127523c61f6bc57a611d97d333bce0d8fe00ab81af4cChet Haase if (newValues != null) { 1276af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase for (String key : oldValues.values.keySet()) { 1277af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase Object oldValue = oldValues.values.get(key); 1278af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase Object newValue = newValues.values.get(key); 1279af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (oldValue != null && newValue != null && 1280af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase !oldValue.equals(newValue)) { 1281af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase cancel = true; 1282af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (DBG) { 1283af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase Log.d(LOG_TAG, "Transition.playTransition: " + 1284af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase "oldValue != newValue for " + key + 1285af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase ": old, new = " + oldValue + ", " + newValue); 1286af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase } 1287af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase break; 1288199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1289199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1290199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1291199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1292199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (cancel) { 1293199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (anim.isRunning() || anim.isStarted()) { 1294199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 1295199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Log.d(LOG_TAG, "Canceling anim " + anim); 1296199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1297199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase anim.cancel(); 1298199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } else { 1299199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 1300199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Log.d(LOG_TAG, "removing anim from info list: " + anim); 1301199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1302199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.remove(anim); 1303199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1304199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1305199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1306199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1307199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1308199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1309d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase createAnimators(sceneRoot, mStartValues, mEndValues); 1310d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase runAnimators(); 1311faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1312faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1313faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1314faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This is a utility method used by subclasses to handle standard parts of 1315faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * setting up and running an Animator: it sets the {@link #getDuration() 1316faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * duration} and the {@link #getStartDelay() startDelay}, starts the 1317199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation, and, when the animator ends, calls {@link #end()}. 1318faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1319faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param animator The Animator to be run during this transition. 1320faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1321faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1322faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1323faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase protected void animate(Animator animator) { 1324faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // TODO: maybe pass auto-end as a boolean parameter? 1325faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (animator == null) { 1326199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 1327faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1328faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getDuration() >= 0) { 1329faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.setDuration(getDuration()); 1330faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1331faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getStartDelay() >= 0) { 1332faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.setStartDelay(getStartDelay()); 1333faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1334faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getInterpolator() != null) { 1335faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.setInterpolator(getInterpolator()); 1336faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1337faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.addListener(new AnimatorListenerAdapter() { 1338faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1339faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onAnimationEnd(Animator animation) { 1340199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 1341faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animation.removeListener(this); 1342faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1343faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase }); 1344faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.start(); 1345faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1346faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1347faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1348faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1349faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method is called automatically by the transition and 1350d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet classes prior to a Transition subclass starting; 1351faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * subclasses should not need to call it directly. 1352faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1353faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1354faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1355199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void start() { 1356faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mNumInstances == 0) { 1357faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1358faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1359faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1360faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1361faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1362faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionStart(this); 1363faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1364faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1365a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mEnded = false; 1366faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1367faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mNumInstances++; 1368faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1369faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1370faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1371faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method is called automatically by the Transition and 1372d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet classes when a transition finishes, either because 1373faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * a transition did nothing (returned a null Animator from 1374d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link Transition#createAnimator(ViewGroup, TransitionValues, 1375faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * TransitionValues)}) or because the transition returned a valid 1376199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Animator and end() was called in the onAnimationEnd() 1377faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * callback of the AnimatorListener. 1378faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1379faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1380faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1381199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void end() { 1382faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase --mNumInstances; 1383faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mNumInstances == 0) { 1384faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1385faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1386faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1387faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1388faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1389faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionEnd(this); 1390faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1391faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 13926ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < mStartValues.itemIdValues.size(); ++i) { 13936ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues tv = mStartValues.itemIdValues.valueAt(i); 1394faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase View v = tv.view; 1395faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (v.hasTransientState()) { 1396faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase v.setHasTransientState(false); 1397faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1398faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 13996ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < mEndValues.itemIdValues.size(); ++i) { 14006ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValues tv = mEndValues.itemIdValues.valueAt(i); 1401faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase View v = tv.view; 1402faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (v.hasTransientState()) { 1403faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase v.setHasTransientState(false); 1404faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1405faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1406a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mEnded = true; 1407faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1408faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1409faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1410faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1411faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method cancels a transition that is currently running. 1412d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 1413d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @hide 1414faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1415199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void cancel() { 1416e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase int numAnimators = mCurrentAnimators.size(); 141725a738fb257aacfc87d3363a834ed6e0b050c3b1Chet Haase for (int i = numAnimators - 1; i >= 0; i--) { 1418e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase Animator animator = mCurrentAnimators.get(i); 1419e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animator.cancel(); 1420e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 1421faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1422faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1423faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1424faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1425faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1426faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionCancel(this); 1427faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1428faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1429faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1430faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1431faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1432faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Adds a listener to the set of listeners that are sent events through the 1433faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * life of an animation, such as start, repeat, and end. 1434faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1435faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param listener the listener to be added to the current set of listeners 1436faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * for this animation. 1437d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 1438faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1439d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition addListener(TransitionListener listener) { 1440faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners == null) { 1441faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners = new ArrayList<TransitionListener>(); 1442faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1443faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners.add(listener); 1444d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1445faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1446faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1447faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1448faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Removes a listener from the set listening to this animation. 1449faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1450faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param listener the listener to be removed from the current set of 1451faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listeners for this transition. 1452d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 1453faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1454d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition removeListener(TransitionListener listener) { 1455faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners == null) { 1456d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1457faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1458faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners.remove(listener); 1459faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners.size() == 0) { 1460faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners = null; 1461faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1462d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1463faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1464faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1465d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Transition setSceneRoot(ViewGroup sceneRoot) { 14666ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mSceneRoot = sceneRoot; 1467d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 14686ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 14696ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 1470b7a7fc9d233bad507ce893882352618b13647058Chet Haase void setCanRemoveViews(boolean canRemoveViews) { 1471b7a7fc9d233bad507ce893882352618b13647058Chet Haase mCanRemoveViews = canRemoveViews; 1472b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 1473b7a7fc9d233bad507ce893882352618b13647058Chet Haase 14740a778eda690a66173733a63622886e888d405c45George Mount public boolean canRemoveViews() { 14750a778eda690a66173733a63622886e888d405c45George Mount return mCanRemoveViews; 14760a778eda690a66173733a63622886e888d405c45George Mount } 14770a778eda690a66173733a63622886e888d405c45George Mount 1478faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1479faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public String toString() { 1480faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return toString(""); 1481faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1482faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 14836ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase @Override 14846ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase public Transition clone() { 14856ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase Transition clone = null; 14866ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase try { 14876ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase clone = (Transition) super.clone(); 1488199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase clone.mAnimators = new ArrayList<Animator>(); 14897660d121b2ef21164ed33e6091e5dd50f5d0f939Chet Haase clone.mStartValues = new TransitionValuesMaps(); 14907660d121b2ef21164ed33e6091e5dd50f5d0f939Chet Haase clone.mEndValues = new TransitionValuesMaps(); 14916ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } catch (CloneNotSupportedException e) {} 14926ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 14936ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return clone; 14946ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 14956ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 1496199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1497199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the name of this Transition. This name is used internally to distinguish 1498199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * between different transitions to determine when interrupting transitions overlap. 1499d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * For example, a ChangeBounds running on the same target view as another ChangeBounds 1500d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should determine whether the old transition is animating to different end values 1501d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * and should be canceled in favor of the new transition. 1502199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1503199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * <p>By default, a Transition's name is simply the value of {@link Class#getName()}, 1504199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * but subclasses are free to override and return something different.</p> 1505199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1506199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return The name of this transition. 1507199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1508199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public String getName() { 1509199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return mName; 1510199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1511199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1512faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase String toString(String indent) { 1513faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase String result = indent + getClass().getSimpleName() + "@" + 1514faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase Integer.toHexString(hashCode()) + ": "; 1515c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mDuration != -1) { 1516c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "dur(" + mDuration + ") "; 1517c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1518c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mStartDelay != -1) { 1519c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "dly(" + mStartDelay + ") "; 1520c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1521c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mInterpolator != null) { 1522c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "interp(" + mInterpolator + ") "; 1523c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1524d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0 || mTargets.size() > 0) { 1525c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "tgts("; 1526d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0) { 1527d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargetIds.size(); ++i) { 1528c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (i > 0) { 1529c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ", "; 1530c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1531d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase result += mTargetIds.get(i); 1532faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1533faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1534d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargets.size() > 0) { 1535d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargets.size(); ++i) { 1536c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (i > 0) { 1537c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ", "; 1538c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1539d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase result += mTargets.get(i); 1540faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1541faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1542c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ")"; 1543faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1544faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return result; 1545faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1546faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1547faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1548faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * A transition listener receives notifications from a transition. 1549199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notifications indicate transition lifecycle events. 1550faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1551faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public static interface TransitionListener { 1552faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1553faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the start of the transition. 1554faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1555faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The started transition. 1556faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1557faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionStart(Transition transition); 1558faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1559faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1560faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the end of the transition. Canceled transitions 1561faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will always notify listeners of both the cancellation and end 1562199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * events. That is, {@link #onTransitionEnd(Transition)} is always called, 1563faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * regardless of whether the transition was canceled or played 1564faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * through to completion. 1565faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1566faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The transition which reached its end. 1567faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1568faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionEnd(Transition transition); 1569faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1570faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1571faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the cancellation of the transition. 1572d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that cancel may be called by a parent {@link TransitionSet} on 1573199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 1574199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state on target objects which was set at 1575d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 1576d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimator()} time. 1577faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1578faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The transition which was canceled. 1579faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1580faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionCancel(Transition transition); 1581199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1582199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1583199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notification when a transition is paused. 1584d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that createAnimator() may be called by a parent {@link TransitionSet} on 1585199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 1586199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state on target objects which was set at 1587d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 1588d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimator()} time. 1589199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1590199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @param transition The transition which was paused. 1591199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1592199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase void onTransitionPause(Transition transition); 1593199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1594199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1595199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notification when a transition is resumed. 1596d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that resume() may be called by a parent {@link TransitionSet} on 1597199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 1598199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state which may have changed in an earlier call 1599199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * to {@link #onTransitionPause(Transition)}. 1600199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1601199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @param transition The transition which was resumed. 1602199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1603199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase void onTransitionResume(Transition transition); 1604faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1605faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1606faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1607faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Utility adapter class to avoid having to override all three methods 1608faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * whenever someone just wants to listen for a single event. 1609faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1610faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1611faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * */ 1612faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public static class TransitionListenerAdapter implements TransitionListener { 1613faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1614faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionStart(Transition transition) { 1615faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1616faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1617faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1618faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionEnd(Transition transition) { 1619faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1620faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1621faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1622faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionCancel(Transition transition) { 1623faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1624199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1625199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase @Override 1626199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void onTransitionPause(Transition transition) { 1627199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1628199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1629199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase @Override 1630199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void onTransitionResume(Transition transition) { 1631199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1632faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1633faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1634199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1635199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Holds information about each animator used when a new transition starts 1636199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * while other transitions are still running to determine whether a running 1637199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation should be canceled or a new animation noop'd. The structure holds 1638199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * information about the state that an animation is going to, to be compared to 1639199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * end state of a new animation. 16400a778eda690a66173733a63622886e888d405c45George Mount * @hide 1641199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 16420a778eda690a66173733a63622886e888d405c45George Mount public static class AnimationInfo { 16430a778eda690a66173733a63622886e888d405c45George Mount public View view; 1644199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase String name; 1645199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues values; 1646199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1647199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase AnimationInfo(View view, String name, TransitionValues values) { 1648199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.view = view; 1649199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.name = name; 1650199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.values = values; 1651199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1652199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1653ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1654ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1655ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility class for managing typed ArrayLists efficiently. In particular, this 1656ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * can be useful for lists that we don't expect to be used often (eg, the exclude 1657ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * lists), so we'd like to keep them nulled out by default. This causes the code to 1658ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * become tedious, with constant null checks, code to allocate when necessary, 1659ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * and code to null out the reference when the list is empty. This class encapsulates 1660ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * all of that functionality into simple add()/remove() methods which perform the 1661ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * necessary checks, allocation/null-out as appropriate, and return the 1662ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * resulting list. 1663ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1664ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private static class ArrayListManager { 1665ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1666ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1667ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Add the specified item to the list, returning the resulting list. 1668ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * The returned list can either the be same list passed in or, if that 1669ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list was null, the new list that was created. 1670ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1671ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Note that the list holds unique items; if the item already exists in the 1672ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list, the list is not modified. 1673ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1674ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase static <T> ArrayList<T> add(ArrayList<T> list, T item) { 1675ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list == null) { 1676ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = new ArrayList<T>(); 1677ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1678ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (!list.contains(item)) { 1679ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list.add(item); 1680ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1681ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 1682ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1683ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1684ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1685ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Remove the specified item from the list, returning the resulting list. 1686ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * The returned list can either the be same list passed in or, if that 1687ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list becomes empty as a result of the remove(), the new list was created. 1688ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1689ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase static <T> ArrayList<T> remove(ArrayList<T> list, T item) { 1690ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list != null) { 1691ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list.remove(item); 1692ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list.isEmpty()) { 1693ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = null; 1694ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1695ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1696ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 1697ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1698ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1699ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1700faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase} 1701