Transition.java revision d4c3c91dd0757eec9703ef90ea4c5a7ee99f18ca
1faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/* 2faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Copyright (C) 2013 The Android Open Source Project 3faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 4faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Licensed under the Apache License, Version 2.0 (the "License"); 5faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * you may not use this file except in compliance with the License. 6faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * You may obtain a copy of the License at 7faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 8faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * http://www.apache.org/licenses/LICENSE-2.0 9faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 10faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Unless required by applicable law or agreed to in writing, software 11faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * distributed under the License is distributed on an "AS IS" BASIS, 12faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * See the License for the specific language governing permissions and 14faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * limitations under the License. 15faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 166ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 17d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haasepackage android.transition; 18faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 19faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.Animator; 20faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.AnimatorListenerAdapter; 21faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.animation.TimeInterpolator; 22d6107a3170df61d9e776fcd5666acfc9135c6f16George Mountimport android.graphics.Rect; 2308735185f8105710e18ad02297461bec9268e514Chet Haaseimport android.util.ArrayMap; 24c43524f3869cc0d36974fce61986017093f2ecd2Chet Haaseimport android.util.Log; 25faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.util.LongSparseArray; 26faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.util.SparseArray; 27d6107a3170df61d9e776fcd5666acfc9135c6f16George Mountimport android.util.SparseLongArray; 28faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.SurfaceView; 29faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.TextureView; 30faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.View; 31faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewGroup; 32faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewOverlay; 33cf68aad3164303df59b2a669d186a94533c9c743George Mountimport android.view.WindowId; 34faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.widget.ListView; 35ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haaseimport android.widget.Spinner; 36faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 37faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport java.util.ArrayList; 38d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haaseimport java.util.List; 39faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 40faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/** 41faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * A Transition holds information about animations that will be run on its 42faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * targets during a scene change. Subclasses of this abstract class may 43d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * choreograph several child transitions ({@link TransitionSet} or they may 44faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * perform custom animations themselves. Any Transition has two main jobs: 45faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (1) capture property values, and (2) play animations based on changes to 46faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * captured property values. A custom transition knows what property values 47faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on View objects are of interest to it, and also knows how to animate 48faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes to those values. For example, the {@link Fade} transition tracks 49faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes to visibility-related properties and is able to construct and run 50faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animations that fade items in or out based on changes to those properties. 51faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 52faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>Note: Transitions may not work correctly with either {@link SurfaceView} 53faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * or {@link TextureView}, due to the way that these views are displayed 54faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on the screen. For SurfaceView, the problem is that the view is updated from 55faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * a non-UI thread, so changes to the view due to transitions (such as moving 56faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * and resizing the view) may be out of sync with the display inside those bounds. 57faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * TextureView is more compatible with transitions in general, but some 58d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * specific transitions (such as {@link Fade}) may not be compatible 59faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * with TextureView because they rely on {@link ViewOverlay} functionality, 60faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * which does not currently work with TextureView.</p> 61d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 62d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Transitions can be declared in XML resource files inside the <code>res/transition</code> 63d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * directory. Transition resources consist of a tag name for one of the Transition 64d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * subclasses along with attributes to define some of the attributes of that transition. 65d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition: 66d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 67d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@sample development/samples/ApiDemos/res/transition/changebounds.xml ChangeBounds} 68d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 69608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * <p>This TransitionSet contains {@link android.transition.Explode} for visibility, 70608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * {@link android.transition.ChangeBounds}, {@link android.transition.ChangeTransform}, 71608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * and {@link android.transition.ChangeClipBounds} for non-<code>ImageView</code>s and 72608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * {@link android.transition.MoveImage} for <code>ImageView</code>s:</p> 73d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 74608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * {@sample development/samples/ApiDemos/res/transition/explode_move_together.xml MultipleTransform} 75d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 76d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Note that attributes for the transition are not required, just as they are 77d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * optional when declared in code; Transitions created from XML resources will use 78d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * the same defaults as their code-created equivalents. Here is a slightly more 79d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * elaborate example which declares a {@link TransitionSet} transition with 80d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link ChangeBounds} and {@link Fade} child transitions:</p> 81d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 82d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@sample 83d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * development/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml TransitionSet} 84d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 85d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>In this example, the transitionOrdering attribute is used on the TransitionSet 86d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * object to change from the default {@link TransitionSet#ORDERING_TOGETHER} behavior 87d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * to be {@link TransitionSet#ORDERING_SEQUENTIAL} instead. Also, the {@link Fade} 88d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition uses a fadingMode of {@link Fade#OUT} instead of the default 89d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * out-in behavior. Finally, note the use of the <code>targets</code> sub-tag, which 90d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * takes a set of {@link android.R.styleable#TransitionTarget target} tags, each 91a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * of which lists a specific <code>targetId</code>, <code>targetClass</code>, 9230da61d477bcb6cc7718f9516c444359352fe148George Mount * <code>targetViewName</code>, <code>excludeId</code>, <code>excludeClass</code>, or 9330da61d477bcb6cc7718f9516c444359352fe148George Mount * <code>excludeViewName</code>, which this transition acts upon. 94d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Use of targets is optional, but can be used to either limit the time spent checking 95d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * attributes on unchanging views, or limiting the types of animations run on specific views. 96d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * In this case, we know that only the <code>grayscaleContainer</code> will be 97d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * disappearing, so we choose to limit the {@link Fade} transition to only that view.</p> 98d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 99d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Further information on XML resource descriptions for transitions can be found for 100d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet}, 101d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade}, and 102d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.R.styleable#Slide}. 103d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 104faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1056ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haasepublic abstract class Transition implements Cloneable { 106faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 107faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private static final String LOG_TAG = "Transition"; 108faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase static final boolean DBG = false; 109faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1107b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 1117b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * With {@link #setMatchOrder(int...)}, chooses to match by View instance. 1127b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 1137b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount public static final int MATCH_INSTANCE = 0x1; 1147b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static final int MATCH_FIRST = MATCH_INSTANCE; 1157b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 1167b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 1177b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * With {@link #setMatchOrder(int...)}, chooses to match by 1187b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * {@link android.view.View#getViewName()}. Null names will not be matched. 1197b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 1207b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount public static final int MATCH_VIEW_NAME = 0x2; 1217b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 1227b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 1237b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * With {@link #setMatchOrder(int...)}, chooses to match by 1247b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * {@link android.view.View#getId()}. Negative IDs will not be matched. 1257b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 1267b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount public static final int MATCH_ID = 0x3; 1277b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 1287b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 1297b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * With {@link #setMatchOrder(int...)}, chooses to match by the {@link android.widget.Adapter} 1307b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * item id. When {@link android.widget.Adapter#hasStableIds()} returns false, no match 1317b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * will be made for items. 1327b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 1337b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount public static final int MATCH_ITEM_ID = 0x4; 1347b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 1357b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static final int MATCH_LAST = MATCH_ITEM_ID; 1367b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 1377b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static final int[] DEFAULT_MATCH_ORDER = { 1387b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount MATCH_VIEW_NAME, 1397b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount MATCH_INSTANCE, 1407b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount MATCH_ID, 1417b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount MATCH_ITEM_ID, 1427b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount }; 1437b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 144199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private String mName = getClass().getName(); 145199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 146faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long mStartDelay = -1; 147faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long mDuration = -1; 148faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TimeInterpolator mInterpolator = null; 149d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase ArrayList<Integer> mTargetIds = new ArrayList<Integer>(); 150d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase ArrayList<View> mTargets = new ArrayList<View>(); 15130da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<String> mTargetNames = null; 15230da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<Class> mTargetTypes = null; 153ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Integer> mTargetIdExcludes = null; 154ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<View> mTargetExcludes = null; 155ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Class> mTargetTypeExcludes = null; 15630da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<String> mTargetNameExcludes = null; 157ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Integer> mTargetIdChildExcludes = null; 158ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<View> mTargetChildExcludes = null; 159ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Class> mTargetTypeChildExcludes = null; 1606ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private TransitionValuesMaps mStartValues = new TransitionValuesMaps(); 1616ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private TransitionValuesMaps mEndValues = new TransitionValuesMaps(); 162d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase TransitionSet mParent = null; 1637b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private int[] mMatchOrder = DEFAULT_MATCH_ORDER; 1646ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 165199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Per-animator information used for later canceling when future transitions overlap 166199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators = 167199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase new ThreadLocal<ArrayMap<Animator, AnimationInfo>>(); 168199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 169d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // Scene Root is set at createAnimator() time in the cloned Transition 1706ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase ViewGroup mSceneRoot = null; 1716ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 172b7a7fc9d233bad507ce893882352618b13647058Chet Haase // Whether removing views from their parent is possible. This is only for views 173b7a7fc9d233bad507ce893882352618b13647058Chet Haase // in the start scene, which are no longer in the view hierarchy. This property 174b7a7fc9d233bad507ce893882352618b13647058Chet Haase // is determined by whether the previous Scene was created from a layout 175b7a7fc9d233bad507ce893882352618b13647058Chet Haase // resource, and thus the views from the exited scene are going away anyway 176b7a7fc9d233bad507ce893882352618b13647058Chet Haase // and can be removed as necessary to achieve a particular effect, such as 177b7a7fc9d233bad507ce893882352618b13647058Chet Haase // removing them from parents to add them to overlays. 178b7a7fc9d233bad507ce893882352618b13647058Chet Haase boolean mCanRemoveViews = false; 179b7a7fc9d233bad507ce893882352618b13647058Chet Haase 180e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // Track all animators in use in case the transition gets canceled and needs to 181e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // cancel running animators 182e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase private ArrayList<Animator> mCurrentAnimators = new ArrayList<Animator>(); 183e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase 184faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Number of per-target instances of this Transition currently running. This count is 185199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // determined by calls to start() and end() 186faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int mNumInstances = 0; 187faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 188199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Whether this transition is currently paused, due to a call to pause() 189199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase boolean mPaused = false; 190c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase 191a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase // Whether this transition has ended. Used to avoid pause/resume on transitions 192a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase // that have completed 193a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase private boolean mEnded = false; 194a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase 195c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase // The set of listeners to be sent transition lifecycle events. 196faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> mListeners = null; 197faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 198d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // The set of animators collected from calls to createAnimator(), 199d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // to be run in runAnimators() 200199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayList<Animator> mAnimators = new ArrayList<Animator>(); 201c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase 202d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // The function for calculating the Animation start delay. 203d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount TransitionPropagation mPropagation; 204d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 205d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // The rectangular region for Transitions like Explode and TransitionPropagations 206d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // like CircularPropagation 207d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount EpicenterCallback mEpicenterCallback; 208d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 209d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // For Fragment shared element transitions, linking views explicitly by mismatching 210d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // viewNames. 211d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount ArrayMap<String, String> mNameOverrides; 212d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount 213faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 214faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Constructs a Transition object with no target objects. A transition with 215faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * no targets defaults to running on all target objects in the scene hierarchy 216d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * (if the transition is not contained in a TransitionSet), or all target 217d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * objects passed down from its parent (if it is in a TransitionSet). 218faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 219faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public Transition() {} 220faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 221faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 222faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the duration of this transition. By default, there is no duration 223faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (indicated by a negative number), which means that the Animator created by 224faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition will have its own specified duration. If the duration of a 225faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that duration will override the Animator duration. 226faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 227faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param duration The length of the animation, in milliseconds. 228faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return This transition object. 229d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_duration 230faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 231faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public Transition setDuration(long duration) { 232faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mDuration = duration; 233faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 234faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 235faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 236199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 237199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the duration set on this transition. If no duration has been set, 238199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be negative, indicating that resulting animators will 239199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own durations. 240199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 241d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The duration set on this transition, in milliseconds, if one has been 242d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * set, otherwise returns a negative number. 243199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 244faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public long getDuration() { 245faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mDuration; 246faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 247faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 248faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 249faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the startDelay of this transition. By default, there is no delay 250faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (indicated by a negative number), which means that the Animator created by 251faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition will have its own specified startDelay. If the delay of a 252faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that delay will override the Animator delay. 253faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 254faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param startDelay The length of the delay, in milliseconds. 255d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 256d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_startDelay 257faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 258d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition setStartDelay(long startDelay) { 259faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mStartDelay = startDelay; 260d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 261faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 262faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 263199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 264199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the startDelay set on this transition. If no startDelay has been set, 265199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be negative, indicating that resulting animators will 266199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own startDelays. 267199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 268d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The startDelay set on this transition, in milliseconds, if one has 269d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * been set, otherwise returns a negative number. 270199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 271faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public long getStartDelay() { 272faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mStartDelay; 273faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 274faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 275faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 276faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the interpolator of this transition. By default, the interpolator 277faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is null, which means that the Animator created by the transition 278faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will have its own specified interpolator. If the interpolator of a 279faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that interpolator will override the Animator interpolator. 280faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 281faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param interpolator The time interpolator used by the transition 282d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 283d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_interpolator 284faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 285d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition setInterpolator(TimeInterpolator interpolator) { 286faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mInterpolator = interpolator; 287d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 288faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 289faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 290199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 291199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the interpolator set on this transition. If no interpolator has been set, 292199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be null, indicating that resulting animators will 293199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own interpolators. 294199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 295199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return The interpolator set on this transition, if one has been set, otherwise 296199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * returns null. 297199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 298faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public TimeInterpolator getInterpolator() { 299faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mInterpolator; 300faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 301faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 302faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 303199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the set of property names used stored in the {@link TransitionValues} 304d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * object passed into {@link #captureStartValues(TransitionValues)} that 305199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * this transition cares about for the purposes of canceling overlapping animations. 306199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * When any transition is started on a given scene root, all transitions 307199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * currently running on that same scene root are checked to see whether the 308199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * properties on which they based their animations agree with the end values of 309199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the same properties in the new transition. If the end values are not equal, 310199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * then the old animation is canceled since the new transition will start a new 311199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation to these new values. If the values are equal, the old animation is 312199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * allowed to continue and no new animation is started for that transition. 313199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 314199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * <p>A transition does not need to override this method. However, not doing so 315199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * will mean that the cancellation logic outlined in the previous paragraph 316199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * will be skipped for that transition, possibly leading to artifacts as 317199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * old transitions and new transitions on the same targets run in parallel, 318199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animating views toward potentially different end values.</p> 319199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 320199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return An array of property names as described in the class documentation for 321199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * {@link TransitionValues}. The default implementation returns <code>null</code>. 322199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 323199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public String[] getTransitionProperties() { 324199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return null; 325199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 326199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 327199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 328d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * This method creates an animation that will be run for this transition 329d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * given the information in the startValues and endValues structures captured 330d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * earlier for the start and end scenes. Subclasses of Transition should override 331d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * this method. The method should only be called by the transition system; it is 332d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * not intended to be called from external classes. 333d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 334d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>This method is called by the transition's parent (all the way up to the 335faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * topmost Transition in the hierarchy) with the sceneRoot and start/end 3362ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * values that the transition may need to set up initial target values 3372ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * and construct an appropriate animation. For example, if an overall 338d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Transition is a {@link TransitionSet} consisting of several 339faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * child transitions in sequence, then some of the child transitions may 340faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * want to set initial values on target views prior to the overall 3412ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * Transition commencing, to put them in an appropriate state for the 342faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * delay between that start and the child Transition start time. For 343faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * example, a transition that fades an item in may wish to set the starting 344faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * alpha value to 0, to avoid it blinking in prior to the transition 345faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * actually starting the animation. This is necessary because the scene 346faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * change that triggers the Transition will automatically set the end-scene 347faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on all target views, so a Transition that wants to animate from a 348d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * different value should set that value prior to returning from this method.</p> 349faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 350faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>Additionally, a Transition can perform logic to determine whether 351faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition needs to run on the given target and start/end values. 352faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * For example, a transition that resizes objects on the screen may wish 353faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * to avoid running for views which are not present in either the start 354d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * or end scenes.</p> 3552ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * 3562ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <p>If there is an animator created and returned from this method, the 3572ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * transition mechanism will apply any applicable duration, startDelay, 3582ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * and interpolator to that animation and start it. A return value of 3592ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <code>null</code> indicates that no animation should run. The default 3602ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * implementation returns null.</p> 361faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 362faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>The method is called for every applicable target object, which is 363faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * stored in the {@link TransitionValues#view} field.</p> 364faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 365d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 366d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param sceneRoot The root of the transition hierarchy. 367d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param startValues The values for a specific target in the start scene. 368d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param endValues The values for the target in the end scene. 369d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return A Animator to be started at the appropriate time in the 370d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * overall transition for this scene change. A null value means no animation 371d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should be run. 372faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 373d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, 374faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues endValues) { 3752ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase return null; 376faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 377faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 378faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 3797b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * Sets the order in which Transition matches View start and end values. 3807b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * <p> 3817b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * The default behavior is to match first by {@link android.view.View#getViewName()}, 3827b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * then by View instance, then by {@link android.view.View#getId()} and finally 3837b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * by its item ID if it is in a direct child of ListView. The caller can 3847b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * choose to have only some or all of the values of {@link #MATCH_INSTANCE}, 3857b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * {@link #MATCH_VIEW_NAME}, {@link #MATCH_ITEM_ID}, and {@link #MATCH_ID}. Only 3867b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * the match algorithms supplied will be used to determine whether Views are the 3877b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * the same in both the start and end Scene. Views that do not match will be considered 3887b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * as entering or leaving the Scene. 3897b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * </p> 3907b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * @param matches A list of zero or more of {@link #MATCH_INSTANCE}, 3917b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * {@link #MATCH_VIEW_NAME}, {@link #MATCH_ITEM_ID}, and {@link #MATCH_ID}. 3927b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * If none are provided, then the default match order will be set. 3937b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 3947b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount public void setMatchOrder(int... matches) { 3957b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount if (matches == null || matches.length == 0) { 3967b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount mMatchOrder = DEFAULT_MATCH_ORDER; 3977b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } else { 3987b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount for (int i = 0; i < matches.length; i++) { 3997b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount int match = matches[i]; 4007b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount if (!isValidMatch(match)) { 4017b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount throw new IllegalArgumentException("matches contains invalid value"); 4027b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 4037b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount if (alreadyContains(matches, i)) { 4047b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount throw new IllegalArgumentException("matches contains a duplicate value"); 4057b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 4067b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 4077b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount mMatchOrder = matches.clone(); 4087b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 4097b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 4107b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 4117b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static boolean isValidMatch(int match) { 4127b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount return (match >= MATCH_FIRST && match <= MATCH_LAST); 4137b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 4147b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 4157b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static boolean alreadyContains(int[] array, int searchIndex) { 4167b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount int value = array[searchIndex]; 4177b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount for (int i = 0; i < searchIndex; i++) { 4187b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount if (array[i] == value) { 4197b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount return true; 4207b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 4217b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 4227b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount return false; 4237b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 4247b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 4257b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 42630da61d477bcb6cc7718f9516c444359352fe148George Mount * Match start/end values by View instance. Adds matched values to startValuesList 42730da61d477bcb6cc7718f9516c444359352fe148George Mount * and endValuesList and removes them from unmatchedStart and unmatchedEnd. 42830da61d477bcb6cc7718f9516c444359352fe148George Mount */ 42930da61d477bcb6cc7718f9516c444359352fe148George Mount private void matchInstances(ArrayList<TransitionValues> startValuesList, 43030da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<TransitionValues> endValuesList, 43130da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedStart, 43230da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd) { 43330da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = unmatchedStart.size() - 1; i >= 0; i--) { 43430da61d477bcb6cc7718f9516c444359352fe148George Mount View view = unmatchedStart.keyAt(i); 43530da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues end = unmatchedEnd.remove(view); 43630da61d477bcb6cc7718f9516c444359352fe148George Mount if (end != null) { 43730da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues start = unmatchedStart.removeAt(i); 43830da61d477bcb6cc7718f9516c444359352fe148George Mount startValuesList.add(start); 43930da61d477bcb6cc7718f9516c444359352fe148George Mount endValuesList.add(end); 44030da61d477bcb6cc7718f9516c444359352fe148George Mount } 44130da61d477bcb6cc7718f9516c444359352fe148George Mount } 44230da61d477bcb6cc7718f9516c444359352fe148George Mount } 44330da61d477bcb6cc7718f9516c444359352fe148George Mount 44430da61d477bcb6cc7718f9516c444359352fe148George Mount /** 44530da61d477bcb6cc7718f9516c444359352fe148George Mount * Match start/end values by Adapter item ID. Adds matched values to startValuesList 44630da61d477bcb6cc7718f9516c444359352fe148George Mount * and endValuesList and removes them from unmatchedStart and unmatchedEnd, using 44730da61d477bcb6cc7718f9516c444359352fe148George Mount * startItemIds and endItemIds as a guide for which Views have unique item IDs. 44830da61d477bcb6cc7718f9516c444359352fe148George Mount */ 44930da61d477bcb6cc7718f9516c444359352fe148George Mount private void matchItemIds(ArrayList<TransitionValues> startValuesList, 45030da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<TransitionValues> endValuesList, 45130da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedStart, 45230da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd, 45330da61d477bcb6cc7718f9516c444359352fe148George Mount LongSparseArray<View> startItemIds, LongSparseArray<View> endItemIds) { 45430da61d477bcb6cc7718f9516c444359352fe148George Mount int numStartIds = startItemIds.size(); 45530da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < numStartIds; i++) { 45630da61d477bcb6cc7718f9516c444359352fe148George Mount View startView = startItemIds.valueAt(i); 45730da61d477bcb6cc7718f9516c444359352fe148George Mount if (startView != null) { 45830da61d477bcb6cc7718f9516c444359352fe148George Mount View endView = endItemIds.get(startItemIds.keyAt(i)); 45930da61d477bcb6cc7718f9516c444359352fe148George Mount if (endView != null) { 46030da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues startValues = unmatchedStart.get(startView); 46130da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues endValues = unmatchedEnd.get(endView); 46230da61d477bcb6cc7718f9516c444359352fe148George Mount if (startValues != null && endValues != null) { 46330da61d477bcb6cc7718f9516c444359352fe148George Mount startValuesList.add(startValues); 46430da61d477bcb6cc7718f9516c444359352fe148George Mount endValuesList.add(endValues); 46530da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedStart.remove(startView); 46630da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedEnd.remove(endView); 46730da61d477bcb6cc7718f9516c444359352fe148George Mount } 46830da61d477bcb6cc7718f9516c444359352fe148George Mount } 46930da61d477bcb6cc7718f9516c444359352fe148George Mount } 47030da61d477bcb6cc7718f9516c444359352fe148George Mount } 47130da61d477bcb6cc7718f9516c444359352fe148George Mount } 47230da61d477bcb6cc7718f9516c444359352fe148George Mount 47330da61d477bcb6cc7718f9516c444359352fe148George Mount /** 47430da61d477bcb6cc7718f9516c444359352fe148George Mount * Match start/end values by Adapter view ID. Adds matched values to startValuesList 47530da61d477bcb6cc7718f9516c444359352fe148George Mount * and endValuesList and removes them from unmatchedStart and unmatchedEnd, using 47630da61d477bcb6cc7718f9516c444359352fe148George Mount * startIds and endIds as a guide for which Views have unique IDs. 47730da61d477bcb6cc7718f9516c444359352fe148George Mount */ 47830da61d477bcb6cc7718f9516c444359352fe148George Mount private void matchIds(ArrayList<TransitionValues> startValuesList, 47930da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<TransitionValues> endValuesList, 48030da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedStart, 48130da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd, 48230da61d477bcb6cc7718f9516c444359352fe148George Mount SparseArray<View> startIds, SparseArray<View> endIds) { 48330da61d477bcb6cc7718f9516c444359352fe148George Mount int numStartIds = startIds.size(); 48430da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < numStartIds; i++) { 48530da61d477bcb6cc7718f9516c444359352fe148George Mount View startView = startIds.valueAt(i); 48630da61d477bcb6cc7718f9516c444359352fe148George Mount if (startView != null && isValidTarget(startView)) { 48730da61d477bcb6cc7718f9516c444359352fe148George Mount View endView = endIds.get(startIds.keyAt(i)); 48830da61d477bcb6cc7718f9516c444359352fe148George Mount if (endView != null && isValidTarget(endView)) { 48930da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues startValues = unmatchedStart.get(startView); 49030da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues endValues = unmatchedEnd.get(endView); 49130da61d477bcb6cc7718f9516c444359352fe148George Mount if (startValues != null && endValues != null) { 49230da61d477bcb6cc7718f9516c444359352fe148George Mount startValuesList.add(startValues); 49330da61d477bcb6cc7718f9516c444359352fe148George Mount endValuesList.add(endValues); 49430da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedStart.remove(startView); 49530da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedEnd.remove(endView); 49630da61d477bcb6cc7718f9516c444359352fe148George Mount } 49730da61d477bcb6cc7718f9516c444359352fe148George Mount } 49830da61d477bcb6cc7718f9516c444359352fe148George Mount } 49930da61d477bcb6cc7718f9516c444359352fe148George Mount } 50030da61d477bcb6cc7718f9516c444359352fe148George Mount } 50130da61d477bcb6cc7718f9516c444359352fe148George Mount 50230da61d477bcb6cc7718f9516c444359352fe148George Mount /** 50330da61d477bcb6cc7718f9516c444359352fe148George Mount * Match start/end values by Adapter viewName. Adds matched values to startValuesList 50430da61d477bcb6cc7718f9516c444359352fe148George Mount * and endValuesList and removes them from unmatchedStart and unmatchedEnd, using 50530da61d477bcb6cc7718f9516c444359352fe148George Mount * startNames and endNames as a guide for which Views have unique viewNames. 50630da61d477bcb6cc7718f9516c444359352fe148George Mount */ 50730da61d477bcb6cc7718f9516c444359352fe148George Mount private void matchNames(ArrayList<TransitionValues> startValuesList, 50830da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<TransitionValues> endValuesList, 50930da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedStart, 51030da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd, 51130da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<String, View> startNames, ArrayMap<String, View> endNames) { 51230da61d477bcb6cc7718f9516c444359352fe148George Mount int numStartNames = startNames.size(); 51330da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < numStartNames; i++) { 51430da61d477bcb6cc7718f9516c444359352fe148George Mount View startView = startNames.valueAt(i); 51530da61d477bcb6cc7718f9516c444359352fe148George Mount if (startView != null && isValidTarget(startView)) { 51630da61d477bcb6cc7718f9516c444359352fe148George Mount View endView = endNames.get(startNames.keyAt(i)); 51730da61d477bcb6cc7718f9516c444359352fe148George Mount if (endView != null && isValidTarget(endView)) { 51830da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues startValues = unmatchedStart.get(startView); 51930da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues endValues = unmatchedEnd.get(endView); 52030da61d477bcb6cc7718f9516c444359352fe148George Mount if (startValues != null && endValues != null) { 52130da61d477bcb6cc7718f9516c444359352fe148George Mount startValuesList.add(startValues); 52230da61d477bcb6cc7718f9516c444359352fe148George Mount endValuesList.add(endValues); 52330da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedStart.remove(startView); 52430da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedEnd.remove(endView); 52530da61d477bcb6cc7718f9516c444359352fe148George Mount } 52630da61d477bcb6cc7718f9516c444359352fe148George Mount } 52730da61d477bcb6cc7718f9516c444359352fe148George Mount } 52830da61d477bcb6cc7718f9516c444359352fe148George Mount } 52930da61d477bcb6cc7718f9516c444359352fe148George Mount } 53030da61d477bcb6cc7718f9516c444359352fe148George Mount 53130da61d477bcb6cc7718f9516c444359352fe148George Mount /** 53230da61d477bcb6cc7718f9516c444359352fe148George Mount * Adds all values from unmatchedStart and unmatchedEnd to startValuesList and endValuesList, 53330da61d477bcb6cc7718f9516c444359352fe148George Mount * assuming that there is no match between values in the list. 53430da61d477bcb6cc7718f9516c444359352fe148George Mount */ 53530da61d477bcb6cc7718f9516c444359352fe148George Mount private void addUnmatched(ArrayList<TransitionValues> startValuesList, 53630da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<TransitionValues> endValuesList, 53730da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedStart, 53830da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd) { 53930da61d477bcb6cc7718f9516c444359352fe148George Mount // Views that only exist in the start Scene 54030da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < unmatchedStart.size(); i++) { 54130da61d477bcb6cc7718f9516c444359352fe148George Mount startValuesList.add(unmatchedStart.valueAt(i)); 54230da61d477bcb6cc7718f9516c444359352fe148George Mount endValuesList.add(null); 54330da61d477bcb6cc7718f9516c444359352fe148George Mount } 54430da61d477bcb6cc7718f9516c444359352fe148George Mount 54530da61d477bcb6cc7718f9516c444359352fe148George Mount // Views that only exist in the end Scene 54630da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < unmatchedEnd.size(); i++) { 54730da61d477bcb6cc7718f9516c444359352fe148George Mount endValuesList.add(unmatchedEnd.valueAt(i)); 54830da61d477bcb6cc7718f9516c444359352fe148George Mount startValuesList.add(null); 54930da61d477bcb6cc7718f9516c444359352fe148George Mount } 55030da61d477bcb6cc7718f9516c444359352fe148George Mount } 55130da61d477bcb6cc7718f9516c444359352fe148George Mount 5527b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private void matchStartAndEnd(TransitionValuesMaps startValues, 5537b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount TransitionValuesMaps endValues, 5547b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount ArrayList<TransitionValues> startValuesList, 5557b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount ArrayList<TransitionValues> endValuesList) { 5567b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount ArrayMap<View, TransitionValues> unmatchedStart = 5577b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount new ArrayMap<View, TransitionValues>(startValues.viewValues); 5587b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount ArrayMap<View, TransitionValues> unmatchedEnd = 5597b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount new ArrayMap<View, TransitionValues>(endValues.viewValues); 5607b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 5617b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount for (int i = 0; i < mMatchOrder.length; i++) { 5627b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount switch (mMatchOrder[i]) { 5637b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount case MATCH_INSTANCE: 5647b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount matchInstances(startValuesList, endValuesList, unmatchedStart, unmatchedEnd); 5657b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount break; 5667b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount case MATCH_VIEW_NAME: 5677b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount matchNames(startValuesList, endValuesList, unmatchedStart, unmatchedEnd, 5687b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount startValues.nameValues, endValues.nameValues); 5697b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount break; 5707b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount case MATCH_ID: 5717b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount matchIds(startValuesList, endValuesList, unmatchedStart, unmatchedEnd, 5727b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount startValues.idValues, endValues.idValues); 5737b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount break; 5747b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount case MATCH_ITEM_ID: 5757b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount matchItemIds(startValuesList, endValuesList, unmatchedStart, unmatchedEnd, 5767b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount startValues.itemIdValues, endValues.itemIdValues); 5777b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount break; 5787b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5797b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5807b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount addUnmatched(startValuesList, endValuesList, unmatchedStart, unmatchedEnd); 5817b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5827b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 58330da61d477bcb6cc7718f9516c444359352fe148George Mount /** 584d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * This method, essentially a wrapper around all calls to createAnimator for all 585d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * possible target views, is called with the entire set of start/end 586faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * values. The implementation in Transition iterates through these lists 587d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)} 588faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * with each set of start/end values on this transition. The 589d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet subclass overrides this method and delegates it to 5902ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * each of its children in succession. 591faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 592faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 593faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 594d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues, 5956ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValuesMaps endValues) { 596c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 597d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Log.d(LOG_TAG, "createAnimators() for " + this); 598c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 599faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionValues> startValuesList = new ArrayList<TransitionValues>(); 600faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionValues> endValuesList = new ArrayList<TransitionValues>(); 6017b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount matchStartAndEnd(startValues, endValues, startValuesList, endValuesList); 60230da61d477bcb6cc7718f9516c444359352fe148George Mount 603199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 604d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount long minStartDelay = Long.MAX_VALUE; 605d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int minAnimator = mAnimators.size(); 606d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount SparseLongArray startDelays = new SparseLongArray(); 607faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < startValuesList.size(); ++i) { 608faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues start = startValuesList.get(i); 609faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endValuesList.get(i); 610208dcade9373905b7168feb24db141cd71c45159George Mount // Only bother trying to animate with valid values that differ between start/end 611208dcade9373905b7168feb24db141cd71c45159George Mount boolean isInvalidStart = start != null && !isValidTarget(start.view); 612208dcade9373905b7168feb24db141cd71c45159George Mount boolean isInvalidEnd = end != null && !isValidTarget(end.view); 613208dcade9373905b7168feb24db141cd71c45159George Mount boolean isChanged = start != end && (start == null || !start.equals(end)); 614208dcade9373905b7168feb24db141cd71c45159George Mount if (isChanged && !isInvalidStart && !isInvalidEnd) { 615208dcade9373905b7168feb24db141cd71c45159George Mount if (DBG) { 616208dcade9373905b7168feb24db141cd71c45159George Mount View view = (end != null) ? end.view : start.view; 617208dcade9373905b7168feb24db141cd71c45159George Mount Log.d(LOG_TAG, " differing start/end values for view " + view); 618208dcade9373905b7168feb24db141cd71c45159George Mount if (start == null || end == null) { 619208dcade9373905b7168feb24db141cd71c45159George Mount Log.d(LOG_TAG, " " + ((start == null) ? 620208dcade9373905b7168feb24db141cd71c45159George Mount "start null, end non-null" : "start non-null, end null")); 621208dcade9373905b7168feb24db141cd71c45159George Mount } else { 622208dcade9373905b7168feb24db141cd71c45159George Mount for (String key : start.values.keySet()) { 623208dcade9373905b7168feb24db141cd71c45159George Mount Object startValue = start.values.get(key); 624208dcade9373905b7168feb24db141cd71c45159George Mount Object endValue = end.values.get(key); 625208dcade9373905b7168feb24db141cd71c45159George Mount if (startValue != endValue && !startValue.equals(endValue)) { 626208dcade9373905b7168feb24db141cd71c45159George Mount Log.d(LOG_TAG, " " + key + ": start(" + startValue + 627208dcade9373905b7168feb24db141cd71c45159George Mount "), end(" + endValue + ")"); 628c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 629c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 630c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 631208dcade9373905b7168feb24db141cd71c45159George Mount } 632208dcade9373905b7168feb24db141cd71c45159George Mount // TODO: what to do about targetIds and itemIds? 633208dcade9373905b7168feb24db141cd71c45159George Mount Animator animator = createAnimator(sceneRoot, start, end); 634208dcade9373905b7168feb24db141cd71c45159George Mount if (animator != null) { 635208dcade9373905b7168feb24db141cd71c45159George Mount // Save animation info for future cancellation purposes 636208dcade9373905b7168feb24db141cd71c45159George Mount View view = null; 637208dcade9373905b7168feb24db141cd71c45159George Mount TransitionValues infoValues = null; 638208dcade9373905b7168feb24db141cd71c45159George Mount if (end != null) { 639208dcade9373905b7168feb24db141cd71c45159George Mount view = end.view; 640208dcade9373905b7168feb24db141cd71c45159George Mount String[] properties = getTransitionProperties(); 641208dcade9373905b7168feb24db141cd71c45159George Mount if (view != null && properties != null && properties.length > 0) { 642208dcade9373905b7168feb24db141cd71c45159George Mount infoValues = new TransitionValues(); 643208dcade9373905b7168feb24db141cd71c45159George Mount infoValues.view = view; 644208dcade9373905b7168feb24db141cd71c45159George Mount TransitionValues newValues = endValues.viewValues.get(view); 645208dcade9373905b7168feb24db141cd71c45159George Mount if (newValues != null) { 646208dcade9373905b7168feb24db141cd71c45159George Mount for (int j = 0; j < properties.length; ++j) { 647208dcade9373905b7168feb24db141cd71c45159George Mount infoValues.values.put(properties[j], 648208dcade9373905b7168feb24db141cd71c45159George Mount newValues.values.get(properties[j])); 649199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 650208dcade9373905b7168feb24db141cd71c45159George Mount } 651208dcade9373905b7168feb24db141cd71c45159George Mount int numExistingAnims = runningAnimators.size(); 652208dcade9373905b7168feb24db141cd71c45159George Mount for (int j = 0; j < numExistingAnims; ++j) { 653208dcade9373905b7168feb24db141cd71c45159George Mount Animator anim = runningAnimators.keyAt(j); 654208dcade9373905b7168feb24db141cd71c45159George Mount AnimationInfo info = runningAnimators.get(anim); 655208dcade9373905b7168feb24db141cd71c45159George Mount if (info.values != null && info.view == view && 656208dcade9373905b7168feb24db141cd71c45159George Mount ((info.name == null && getName() == null) || 657208dcade9373905b7168feb24db141cd71c45159George Mount info.name.equals(getName()))) { 658208dcade9373905b7168feb24db141cd71c45159George Mount if (info.values.equals(infoValues)) { 659208dcade9373905b7168feb24db141cd71c45159George Mount // Favor the old animator 660208dcade9373905b7168feb24db141cd71c45159George Mount animator = null; 661208dcade9373905b7168feb24db141cd71c45159George Mount break; 662199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 663199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 664199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 665199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 666208dcade9373905b7168feb24db141cd71c45159George Mount } else { 667208dcade9373905b7168feb24db141cd71c45159George Mount view = (start != null) ? start.view : null; 668208dcade9373905b7168feb24db141cd71c45159George Mount } 669208dcade9373905b7168feb24db141cd71c45159George Mount if (animator != null) { 670208dcade9373905b7168feb24db141cd71c45159George Mount if (mPropagation != null) { 671208dcade9373905b7168feb24db141cd71c45159George Mount long delay = mPropagation 672208dcade9373905b7168feb24db141cd71c45159George Mount .getStartDelay(sceneRoot, this, start, end); 673208dcade9373905b7168feb24db141cd71c45159George Mount startDelays.put(mAnimators.size(), delay); 674208dcade9373905b7168feb24db141cd71c45159George Mount minStartDelay = Math.min(delay, minStartDelay); 675199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 676208dcade9373905b7168feb24db141cd71c45159George Mount AnimationInfo info = new AnimationInfo(view, getName(), 677208dcade9373905b7168feb24db141cd71c45159George Mount sceneRoot.getWindowId(), infoValues); 678208dcade9373905b7168feb24db141cd71c45159George Mount runningAnimators.put(animator, info); 679208dcade9373905b7168feb24db141cd71c45159George Mount mAnimators.add(animator); 680c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 681c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 682faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 683faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 684d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (minStartDelay != 0) { 685d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount for (int i = 0; i < startDelays.size(); i++) { 686d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int index = startDelays.keyAt(i); 687d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount Animator animator = mAnimators.get(index); 688d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount long delay = startDelays.valueAt(i) - minStartDelay + animator.getStartDelay(); 689d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount animator.setStartDelay(delay); 690d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 691d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 692faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 693faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 694faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 695faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Internal utility method for checking whether a given view/id 696faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is valid for this transition, where "valid" means that either 697faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition has no target/targetId list (the default, in which 698faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * cause the transition should act on all views in the hiearchy), or 699faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the given view is in the target list or the view id is in the 700faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * targetId list. If the target parameter is null, then the target list 701faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is not checked (this is in the case of ListView items, where the 702faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * views are ignored and only the ids are used). 703faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 70430da61d477bcb6cc7718f9516c444359352fe148George Mount boolean isValidTarget(View target) { 70530da61d477bcb6cc7718f9516c444359352fe148George Mount int targetId = target.getId(); 706ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdExcludes != null && mTargetIdExcludes.contains(targetId)) { 707ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 708ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 709ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetExcludes != null && mTargetExcludes.contains(target)) { 710ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 711ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 712ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes != null && target != null) { 713ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeExcludes.size(); 714ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 715ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase Class type = mTargetTypeExcludes.get(i); 716ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (type.isInstance(target)) { 717ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 718ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 719ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 720ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 72130da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetNameExcludes != null && target != null && target.getViewName() != null) { 72230da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetNameExcludes.contains(target.getViewName())) { 72330da61d477bcb6cc7718f9516c444359352fe148George Mount return false; 72430da61d477bcb6cc7718f9516c444359352fe148George Mount } 72530da61d477bcb6cc7718f9516c444359352fe148George Mount } 72630da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetIds.size() == 0 && mTargets.size() == 0 && 72730da61d477bcb6cc7718f9516c444359352fe148George Mount (mTargetTypes == null || mTargetTypes.isEmpty() && 72830da61d477bcb6cc7718f9516c444359352fe148George Mount (mTargetNames == null || mTargetNames.isEmpty()))) { 72930da61d477bcb6cc7718f9516c444359352fe148George Mount return true; 73030da61d477bcb6cc7718f9516c444359352fe148George Mount } 73130da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetIds.contains(targetId) || mTargets.contains(target)) { 732faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 733faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 73430da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetNames != null && mTargetNames.contains(target.getViewName())) { 735a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount return true; 736faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 737a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount if (mTargetTypes != null) { 738a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount for (int i = 0; i < mTargetTypes.size(); ++i) { 739a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount if (mTargetTypes.get(i).isInstance(target)) { 740faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 741faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 742faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 743faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 744faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return false; 745faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 746faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 747e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() { 748199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get(); 749199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (runningAnimators == null) { 750199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators = new ArrayMap<Animator, AnimationInfo>(); 751199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase sRunningAnimators.set(runningAnimators); 752199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 753199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return runningAnimators; 754199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 755199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 756faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 7572ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * This is called internally once all animations have been set up by the 758d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * transition hierarchy. 759faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 760faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 761faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 762d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase protected void runAnimators() { 763199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 764d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Log.d(LOG_TAG, "runAnimators() on " + this); 765199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 766199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase start(); 767199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 768d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // Now start every Animator that was previously created for this transition 769199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (Animator anim : mAnimators) { 770c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 771c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Log.d(LOG_TAG, " anim: " + anim); 772c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 773199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (runningAnimators.containsKey(anim)) { 774199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase start(); 775199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runAnimator(anim, runningAnimators); 776199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 777faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 778199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mAnimators.clear(); 779199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 780faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 781faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 782199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private void runAnimator(Animator animator, 783199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase final ArrayMap<Animator, AnimationInfo> runningAnimators) { 784e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase if (animator != null) { 785e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // TODO: could be a single listener instance for all of them since it uses the param 786e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animator.addListener(new AnimatorListenerAdapter() { 787e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase @Override 788e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase public void onAnimationStart(Animator animation) { 789e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase mCurrentAnimators.add(animation); 790e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 791e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase @Override 792e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase public void onAnimationEnd(Animator animation) { 793199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.remove(animation); 794e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase mCurrentAnimators.remove(animation); 795e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 796e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase }); 797e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animate(animator); 798e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 799e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 800e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase 801faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 802d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Captures the values in the start scene for the properties that this 803d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition monitors. These values are then passed as the startValues 804d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * structure in a later call to 805d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 806d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The main concern for an implementation is what the 807d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * properties are that the transition cares about and what the values are 808d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * for all of those properties. The start and end values will be compared 809d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * later during the 810d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)} 811d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * method to determine what, if any, animations, should be run. 812d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 813d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Subclasses must implement this method. The method should only be called by the 814d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition system; it is not intended to be called from external classes.</p> 815d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 816d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param transitionValues The holder for any values that the Transition 817d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * wishes to store. Values are stored in the <code>values</code> field 818d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of this TransitionValues object and are keyed from 819d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * a String value. For example, to store a view's rotation value, 820d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * a transition might call 821d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionValues.values.put("appname:transitionname:rotation", 822d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * view.getRotation())</code>. The target view will already be stored in 823d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * the transitionValues structure when this method is called. 824d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 825d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #captureEndValues(TransitionValues) 826d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 827d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 828d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public abstract void captureStartValues(TransitionValues transitionValues); 829d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 830d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 831d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Captures the values in the end scene for the properties that this 832d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition monitors. These values are then passed as the endValues 833d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * structure in a later call to 834d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 835d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The main concern for an implementation is what the 836faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * properties are that the transition cares about and what the values are 837faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * for all of those properties. The start and end values will be compared 8382ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * later during the 839d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)} 8402ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * method to determine what, if any, animations, should be run. 841faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 842d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Subclasses must implement this method. The method should only be called by the 843d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition system; it is not intended to be called from external classes.</p> 844d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 8452ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * @param transitionValues The holder for any values that the Transition 8462ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * wishes to store. Values are stored in the <code>values</code> field 8472ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * of this TransitionValues object and are keyed from 8482ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * a String value. For example, to store a view's rotation value, 8492ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * a transition might call 8502ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <code>transitionValues.values.put("appname:transitionname:rotation", 8512ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * view.getRotation())</code>. The target view will already be stored in 8522ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * the transitionValues structure when this method is called. 853d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 854d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #captureStartValues(TransitionValues) 855d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 856faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 857d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public abstract void captureEndValues(TransitionValues transitionValues); 858faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 859faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 860d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Adds the id of a target view that this Transition is interested in 861faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animating. By default, there are no targetIds, and a Transition will 862faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listen for changes on every view in the hierarchy below the sceneRoot 863d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of the Scene being transitioned into. Setting targetIds constrains 864faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition to only listen for, and act on, views with these IDs. 865faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Views with different IDs, or no IDs whatsoever, will be ignored. 866faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 867d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Note that using ids to specify targets implies that ids should be unique 868d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * within the view hierarchy underneat the scene root.</p> 869d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 870faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @see View#getId() 871d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param targetId The id of a target view, must be a positive number. 872d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition to which the targetId is added. 873d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Returning the same object makes it easier to chain calls during 874d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * construction, such as 875ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <code>transitionSet.addTransitions(new Fade()).addTarget(someId);</code> 876d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 877ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition addTarget(int targetId) { 878d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (targetId > 0) { 879d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargetIds.add(targetId); 880d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 881d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 882d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 883d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 884d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 88530da61d477bcb6cc7718f9516c444359352fe148George Mount * Adds the viewName of a target view that this Transition is interested in 88630da61d477bcb6cc7718f9516c444359352fe148George Mount * animating. By default, there are no targetNames, and a Transition will 88730da61d477bcb6cc7718f9516c444359352fe148George Mount * listen for changes on every view in the hierarchy below the sceneRoot 88830da61d477bcb6cc7718f9516c444359352fe148George Mount * of the Scene being transitioned into. Setting targetNames constrains 88930da61d477bcb6cc7718f9516c444359352fe148George Mount * the Transition to only listen for, and act on, views with these viewNames. 89030da61d477bcb6cc7718f9516c444359352fe148George Mount * Views with different viewNames, or no viewName whatsoever, will be ignored. 89130da61d477bcb6cc7718f9516c444359352fe148George Mount * 89230da61d477bcb6cc7718f9516c444359352fe148George Mount * <p>Note that viewNames should be unique within the view hierarchy.</p> 89330da61d477bcb6cc7718f9516c444359352fe148George Mount * 89430da61d477bcb6cc7718f9516c444359352fe148George Mount * @see android.view.View#getViewName() 89530da61d477bcb6cc7718f9516c444359352fe148George Mount * @param targetName The viewName of a target view, must be non-null. 89630da61d477bcb6cc7718f9516c444359352fe148George Mount * @return The Transition to which the target viewName is added. 89730da61d477bcb6cc7718f9516c444359352fe148George Mount * Returning the same object makes it easier to chain calls during 89830da61d477bcb6cc7718f9516c444359352fe148George Mount * construction, such as 89930da61d477bcb6cc7718f9516c444359352fe148George Mount * <code>transitionSet.addTransitions(new Fade()).addTarget(someName);</code> 90030da61d477bcb6cc7718f9516c444359352fe148George Mount */ 90130da61d477bcb6cc7718f9516c444359352fe148George Mount public Transition addTarget(String targetName) { 90230da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetName != null) { 90330da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetNames != null) { 90430da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetNames = new ArrayList<String>(); 90530da61d477bcb6cc7718f9516c444359352fe148George Mount } 90630da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetNames.add(targetName); 90730da61d477bcb6cc7718f9516c444359352fe148George Mount } 90830da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 90930da61d477bcb6cc7718f9516c444359352fe148George Mount } 91030da61d477bcb6cc7718f9516c444359352fe148George Mount 91130da61d477bcb6cc7718f9516c444359352fe148George Mount /** 912a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * Adds the Class of a target view that this Transition is interested in 913a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * animating. By default, there are no targetTypes, and a Transition will 914a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * listen for changes on every view in the hierarchy below the sceneRoot 915a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * of the Scene being transitioned into. Setting targetTypes constrains 916a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * the Transition to only listen for, and act on, views with these classes. 917a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * Views with different classes will be ignored. 918a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * 919a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * <p>Note that any View that can be cast to targetType will be included, so 920a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * if targetType is <code>View.class</code>, all Views will be included.</p> 921a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * 922a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @see #addTarget(int) 923a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @see #addTarget(android.view.View) 924a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @see #excludeTarget(Class, boolean) 925a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @see #excludeChildren(Class, boolean) 926a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * 927a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @param targetType The type to include when running this transition. 928a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @return The Transition to which the target class was added. 929a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * Returning the same object makes it easier to chain calls during 930a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * construction, such as 931a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * <code>transitionSet.addTransitions(new Fade()).addTarget(ImageView.class);</code> 932a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount */ 933a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount public Transition addTarget(Class targetType) { 93430da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetType != null) { 93530da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetTypes == null) { 93630da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypes = new ArrayList<Class>(); 93730da61d477bcb6cc7718f9516c444359352fe148George Mount } 93830da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypes.add(targetType); 939a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount } 940a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount return this; 941a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount } 942a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount 943a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount /** 944d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Removes the given targetId from the list of ids that this Transition 945d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * is interested in animating. 946d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 947d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param targetId The id of a target view, must be a positive number. 948d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition from which the targetId is removed. 949faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returning the same object makes it easier to chain calls during 950faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * construction, such as 951d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code> 952faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 953ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition removeTarget(int targetId) { 954d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (targetId > 0) { 955d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargetIds.remove(targetId); 956d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 957faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 958faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 959faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 960faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 96130da61d477bcb6cc7718f9516c444359352fe148George Mount * Removes the given targetName from the list of viewNames that this Transition 96230da61d477bcb6cc7718f9516c444359352fe148George Mount * is interested in animating. 96330da61d477bcb6cc7718f9516c444359352fe148George Mount * 96430da61d477bcb6cc7718f9516c444359352fe148George Mount * @param targetName The viewName of a target view, must not be null. 96530da61d477bcb6cc7718f9516c444359352fe148George Mount * @return The Transition from which the targetName is removed. 96630da61d477bcb6cc7718f9516c444359352fe148George Mount * Returning the same object makes it easier to chain calls during 96730da61d477bcb6cc7718f9516c444359352fe148George Mount * construction, such as 96830da61d477bcb6cc7718f9516c444359352fe148George Mount * <code>transitionSet.addTransitions(new Fade()).removeTargetName(someName);</code> 96930da61d477bcb6cc7718f9516c444359352fe148George Mount */ 97030da61d477bcb6cc7718f9516c444359352fe148George Mount public Transition removeTarget(String targetName) { 97130da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetName != null && mTargetNames != null) { 97230da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetNames.remove(targetName); 97330da61d477bcb6cc7718f9516c444359352fe148George Mount } 97430da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 97530da61d477bcb6cc7718f9516c444359352fe148George Mount } 97630da61d477bcb6cc7718f9516c444359352fe148George Mount 97730da61d477bcb6cc7718f9516c444359352fe148George Mount /** 978ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given id to the list of target ids to exclude from this 979ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 980ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should be added to or removed from the excluded list. 981ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 982ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 983ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 984ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 985ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 986ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 987ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 988ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 989ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 990ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 991ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 992ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 993ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param targetId The id of a target to ignore when running this transition. 994ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 995ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 996ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 997ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 998ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(int targetId, boolean exclude) { 99930da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetId >= 0) { 100030da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetIdExcludes = excludeObject(mTargetIdExcludes, targetId, exclude); 100130da61d477bcb6cc7718f9516c444359352fe148George Mount } 100230da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 100330da61d477bcb6cc7718f9516c444359352fe148George Mount } 100430da61d477bcb6cc7718f9516c444359352fe148George Mount 100530da61d477bcb6cc7718f9516c444359352fe148George Mount /** 100630da61d477bcb6cc7718f9516c444359352fe148George Mount * Whether to add the given viewName to the list of target viewNames to exclude from this 100730da61d477bcb6cc7718f9516c444359352fe148George Mount * transition. The <code>exclude</code> parameter specifies whether the target 100830da61d477bcb6cc7718f9516c444359352fe148George Mount * should be added to or removed from the excluded list. 100930da61d477bcb6cc7718f9516c444359352fe148George Mount * 101030da61d477bcb6cc7718f9516c444359352fe148George Mount * <p>Excluding targets is a general mechanism for allowing transitions to run on 101130da61d477bcb6cc7718f9516c444359352fe148George Mount * a view hierarchy while skipping target views that should not be part of 101230da61d477bcb6cc7718f9516c444359352fe148George Mount * the transition. For example, you may want to avoid animating children 101330da61d477bcb6cc7718f9516c444359352fe148George Mount * of a specific ListView or Spinner. Views can be excluded by their 101430da61d477bcb6cc7718f9516c444359352fe148George Mount * id, their instance reference, their viewName, or by the Class of that view 101530da61d477bcb6cc7718f9516c444359352fe148George Mount * (eg, {@link Spinner}).</p> 101630da61d477bcb6cc7718f9516c444359352fe148George Mount * 101730da61d477bcb6cc7718f9516c444359352fe148George Mount * @see #excludeTarget(View, boolean) 101830da61d477bcb6cc7718f9516c444359352fe148George Mount * @see #excludeTarget(int, boolean) 101930da61d477bcb6cc7718f9516c444359352fe148George Mount * @see #excludeTarget(Class, boolean) 102030da61d477bcb6cc7718f9516c444359352fe148George Mount * 102130da61d477bcb6cc7718f9516c444359352fe148George Mount * @param targetViewName The name of a target to ignore when running this transition. 102230da61d477bcb6cc7718f9516c444359352fe148George Mount * @param exclude Whether to add the target to or remove the target from the 102330da61d477bcb6cc7718f9516c444359352fe148George Mount * current list of excluded targets. 102430da61d477bcb6cc7718f9516c444359352fe148George Mount * @return This transition object. 102530da61d477bcb6cc7718f9516c444359352fe148George Mount */ 102630da61d477bcb6cc7718f9516c444359352fe148George Mount public Transition excludeTarget(String targetViewName, boolean exclude) { 102730da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetNameExcludes = excludeObject(mTargetNameExcludes, targetViewName, exclude); 1028ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1029ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1030ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1031ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1032ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the children of the given id to the list of targets to exclude 1033ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * from this transition. The <code>exclude</code> parameter specifies whether 1034ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the children of the target should be added to or removed from the excluded list. 1035ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Excluding children in this way provides a simple mechanism for excluding all 1036ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * children of specific targets, rather than individually excluding each 1037ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * child individually. 1038ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1039ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1040ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1041ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1042ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1043ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1044ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1045ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1046ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 1047ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 1048ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 1049ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1050ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param targetId The id of a target whose children should be ignored when running 1051ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * this transition. 1052ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 1053ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded-child targets. 1054ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1055ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1056ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(int targetId, boolean exclude) { 105730da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetId >= 0) { 105830da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetIdChildExcludes = excludeObject(mTargetIdChildExcludes, targetId, exclude); 1059ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 106030da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 1061ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1062ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1063ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1064ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given target to the list of targets to exclude from this 1065ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 1066ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should be added to or removed from the excluded list. 1067ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1068ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1069ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1070ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1071ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1072ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1073ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1074ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1075ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 1076ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 1077ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 1078ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1079ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param target The target to ignore when running this transition. 1080ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 1081ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 1082ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1083ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1084ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(View target, boolean exclude) { 108530da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetExcludes = excludeObject(mTargetExcludes, target, exclude); 1086ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1087ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1088ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1089ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1090ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the children of given target to the list of target children 1091ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * to exclude from this transition. The <code>exclude</code> parameter specifies 1092ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * whether the target should be added to or removed from the excluded list. 1093ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1094ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1095ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1096ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1097ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1098ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1099ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1100ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1101ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 1102ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 1103ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 1104ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1105ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param target The target to ignore when running this transition. 1106ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 1107ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 1108ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1109ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1110ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(View target, boolean exclude) { 111130da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetChildExcludes = excludeObject(mTargetChildExcludes, target, exclude); 1112ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1113ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1114ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1115ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1116ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility method to manage the boilerplate code that is the same whether we 1117ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * are excluding targets or their children. 1118ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 111930da61d477bcb6cc7718f9516c444359352fe148George Mount private static <T> ArrayList<T> excludeObject(ArrayList<T> list, T target, boolean exclude) { 1120ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (target != null) { 1121ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (exclude) { 1122ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.add(list, target); 1123ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } else { 1124ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.remove(list, target); 1125ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1126ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1127ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 1128ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1129ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1130ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1131ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given type to the list of types to exclude from this 1132ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 1133ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * type should be added to or removed from the excluded list. 1134ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1135ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1136ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1137ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1138ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1139ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1140ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1141ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1142ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 1143ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 1144ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 1145ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1146ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param type The type to ignore when running this transition. 1147ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target type to or remove it from the 1148ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded target types. 1149ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1150ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1151ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(Class type, boolean exclude) { 115230da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypeExcludes = excludeObject(mTargetTypeExcludes, type, exclude); 1153ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1154ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1155ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1156ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1157ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given type to the list of types whose children should 1158ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * be excluded from this transition. The <code>exclude</code> parameter 1159ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * specifies whether the target type should be added to or removed from 1160ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the excluded list. 1161ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1162ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1163ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1164ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1165ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1166ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1167ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1168ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1169ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 1170ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 1171ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 1172ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1173ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param type The type to ignore when running this transition. 1174ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target type to or remove it from the 1175ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded target types. 1176ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1177ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1178ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(Class type, boolean exclude) { 117930da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypeChildExcludes = excludeObject(mTargetTypeChildExcludes, type, exclude); 1180ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1181ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1182ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1183ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1184faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the target view instances that this Transition is interested in 1185faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animating. By default, there are no targets, and a Transition will 1186faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listen for changes on every view in the hierarchy below the sceneRoot 1187faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * of the Scene being transitioned into. Setting targets constrains 1188faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition to only listen for, and act on, these views. 1189faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * All other views will be ignored. 1190faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1191ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>The target list is like the {@link #addTarget(int) targetId} 1192faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * list except this list specifies the actual View instances, not the ids 1193faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * of the views. This is an important distinction when scene changes involve 1194faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * view hierarchies which have been inflated separately; different views may 1195faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * share the same id but not actually be the same instance. If the transition 1196ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should treat those views as the same, then {@link #addTarget(int)} should be used 1197d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve 1198faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes all within the same view hierarchy, among views which do not 1199d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * necessarily have ids set on them, then the target list of views may be more 1200faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * convenient.</p> 1201faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1202ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #addTarget(int) 1203d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param target A View on which the Transition will act, must be non-null. 1204d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition to which the target is added. 1205d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Returning the same object makes it easier to chain calls during 1206d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * construction, such as 1207d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code> 1208d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 1209d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition addTarget(View target) { 1210d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargets.add(target); 1211d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1212d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 1213d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 1214d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 1215d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Removes the given target from the list of targets that this Transition 1216d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * is interested in animating. 1217d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 1218d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param target The target view, must be non-null. 1219d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return Transition The Transition from which the target is removed. 1220faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returning the same object makes it easier to chain calls during 1221faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * construction, such as 1222d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code> 1223faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1224d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition removeTarget(View target) { 1225d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (target != null) { 1226d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargets.remove(target); 1227d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 1228faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 1229faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1230faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1231faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 123230da61d477bcb6cc7718f9516c444359352fe148George Mount * Removes the given target from the list of targets that this Transition 123330da61d477bcb6cc7718f9516c444359352fe148George Mount * is interested in animating. 123430da61d477bcb6cc7718f9516c444359352fe148George Mount * 123530da61d477bcb6cc7718f9516c444359352fe148George Mount * @param target The type of the target view, must be non-null. 123630da61d477bcb6cc7718f9516c444359352fe148George Mount * @return Transition The Transition from which the target is removed. 123730da61d477bcb6cc7718f9516c444359352fe148George Mount * Returning the same object makes it easier to chain calls during 123830da61d477bcb6cc7718f9516c444359352fe148George Mount * construction, such as 123930da61d477bcb6cc7718f9516c444359352fe148George Mount * <code>transitionSet.addTransitions(new Fade()).removeTarget(someType);</code> 124030da61d477bcb6cc7718f9516c444359352fe148George Mount */ 124130da61d477bcb6cc7718f9516c444359352fe148George Mount public Transition removeTarget(Class target) { 124230da61d477bcb6cc7718f9516c444359352fe148George Mount if (target != null) { 124330da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypes.remove(target); 124430da61d477bcb6cc7718f9516c444359352fe148George Mount } 124530da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 124630da61d477bcb6cc7718f9516c444359352fe148George Mount } 124730da61d477bcb6cc7718f9516c444359352fe148George Mount 124830da61d477bcb6cc7718f9516c444359352fe148George Mount /** 124930da61d477bcb6cc7718f9516c444359352fe148George Mount * Returns the list of target IDs that this transition limits itself to 125030da61d477bcb6cc7718f9516c444359352fe148George Mount * tracking and animating. If the list is null or empty for 125130da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetViewNames()}, and 125230da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetTypes()} then this transition is 1253faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * not limited to specific views, and will handle changes to any views 1254faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * in the hierarchy of a scene change. 1255faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1256faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return the list of target IDs 1257faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1258d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public List<Integer> getTargetIds() { 1259faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mTargetIds; 1260faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1261faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1262faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 126330da61d477bcb6cc7718f9516c444359352fe148George Mount * Returns the list of target views that this transition limits itself to 126430da61d477bcb6cc7718f9516c444359352fe148George Mount * tracking and animating. If the list is null or empty for 126530da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetViewNames()}, and 126630da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetTypes()} then this transition is 1267faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * not limited to specific views, and will handle changes to any views 1268faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * in the hierarchy of a scene change. 1269faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1270faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return the list of target views 1271faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1272d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public List<View> getTargets() { 1273faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mTargets; 1274faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1275faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1276faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 127730da61d477bcb6cc7718f9516c444359352fe148George Mount * Returns the list of target viewNames that this transition limits itself to 127830da61d477bcb6cc7718f9516c444359352fe148George Mount * tracking and animating. If the list is null or empty for 127930da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetViewNames()}, and 128030da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetTypes()} then this transition is 128130da61d477bcb6cc7718f9516c444359352fe148George Mount * not limited to specific views, and will handle changes to any views 128230da61d477bcb6cc7718f9516c444359352fe148George Mount * in the hierarchy of a scene change. 128330da61d477bcb6cc7718f9516c444359352fe148George Mount * 128430da61d477bcb6cc7718f9516c444359352fe148George Mount * @return the list of target viewNames 128530da61d477bcb6cc7718f9516c444359352fe148George Mount */ 128630da61d477bcb6cc7718f9516c444359352fe148George Mount public List<String> getTargetViewNames() { 128730da61d477bcb6cc7718f9516c444359352fe148George Mount return mTargetNames; 128830da61d477bcb6cc7718f9516c444359352fe148George Mount } 128930da61d477bcb6cc7718f9516c444359352fe148George Mount 129030da61d477bcb6cc7718f9516c444359352fe148George Mount /** 129130da61d477bcb6cc7718f9516c444359352fe148George Mount * Returns the list of target viewNames that this transition limits itself to 129230da61d477bcb6cc7718f9516c444359352fe148George Mount * tracking and animating. If the list is null or empty for 129330da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetViewNames()}, and 129430da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetTypes()} then this transition is 129530da61d477bcb6cc7718f9516c444359352fe148George Mount * not limited to specific views, and will handle changes to any views 129630da61d477bcb6cc7718f9516c444359352fe148George Mount * in the hierarchy of a scene change. 129730da61d477bcb6cc7718f9516c444359352fe148George Mount * 129830da61d477bcb6cc7718f9516c444359352fe148George Mount * @return the list of target Types 129930da61d477bcb6cc7718f9516c444359352fe148George Mount */ 130030da61d477bcb6cc7718f9516c444359352fe148George Mount public List<Class> getTargetTypes() { 130130da61d477bcb6cc7718f9516c444359352fe148George Mount return mTargetTypes; 130230da61d477bcb6cc7718f9516c444359352fe148George Mount } 130330da61d477bcb6cc7718f9516c444359352fe148George Mount 130430da61d477bcb6cc7718f9516c444359352fe148George Mount /** 1305faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Recursive method that captures values for the given view and the 1306faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * hierarchy underneath it. 1307faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param sceneRoot The root of the view hierarchy being captured 1308faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param start true if this capture is happening before the scene change, 1309faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * false otherwise 1310faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1311faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void captureValues(ViewGroup sceneRoot, boolean start) { 1312df32aa87150768795816852c6393306893467ecaChet Haase clearValues(start); 131330da61d477bcb6cc7718f9516c444359352fe148George Mount if ((mTargetIds.size() > 0 || mTargets.size() > 0) 131430da61d477bcb6cc7718f9516c444359352fe148George Mount && (mTargetNames == null || mTargetNames.isEmpty()) 131530da61d477bcb6cc7718f9516c444359352fe148George Mount && (mTargetTypes == null || mTargetTypes.isEmpty())) { 131630da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < mTargetIds.size(); ++i) { 131730da61d477bcb6cc7718f9516c444359352fe148George Mount int id = mTargetIds.get(i); 131830da61d477bcb6cc7718f9516c444359352fe148George Mount View view = sceneRoot.findViewById(id); 131930da61d477bcb6cc7718f9516c444359352fe148George Mount if (view != null) { 132030da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues values = new TransitionValues(); 132130da61d477bcb6cc7718f9516c444359352fe148George Mount values.view = view; 132230da61d477bcb6cc7718f9516c444359352fe148George Mount if (start) { 132330da61d477bcb6cc7718f9516c444359352fe148George Mount captureStartValues(values); 132430da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 132530da61d477bcb6cc7718f9516c444359352fe148George Mount captureEndValues(values); 132630da61d477bcb6cc7718f9516c444359352fe148George Mount } 132730da61d477bcb6cc7718f9516c444359352fe148George Mount capturePropagationValues(values); 132830da61d477bcb6cc7718f9516c444359352fe148George Mount if (start) { 132930da61d477bcb6cc7718f9516c444359352fe148George Mount addViewValues(mStartValues, view, values); 133030da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 133130da61d477bcb6cc7718f9516c444359352fe148George Mount addViewValues(mEndValues, view, values); 1332faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1333faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1334faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 133530da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < mTargets.size(); ++i) { 133630da61d477bcb6cc7718f9516c444359352fe148George Mount View view = mTargets.get(i); 133730da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues values = new TransitionValues(); 133830da61d477bcb6cc7718f9516c444359352fe148George Mount values.view = view; 133930da61d477bcb6cc7718f9516c444359352fe148George Mount if (start) { 134030da61d477bcb6cc7718f9516c444359352fe148George Mount captureStartValues(values); 134130da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 134230da61d477bcb6cc7718f9516c444359352fe148George Mount captureEndValues(values); 134330da61d477bcb6cc7718f9516c444359352fe148George Mount } 134430da61d477bcb6cc7718f9516c444359352fe148George Mount capturePropagationValues(values); 134530da61d477bcb6cc7718f9516c444359352fe148George Mount if (start) { 134630da61d477bcb6cc7718f9516c444359352fe148George Mount mStartValues.viewValues.put(view, values); 134730da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 134830da61d477bcb6cc7718f9516c444359352fe148George Mount mEndValues.viewValues.put(view, values); 1349faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1350faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1351faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1352faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase captureHierarchy(sceneRoot, start); 1353faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1354d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount if (!start && mNameOverrides != null) { 1355d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount int numOverrides = mNameOverrides.size(); 1356d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount ArrayList<View> overriddenViews = new ArrayList<View>(numOverrides); 1357d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount for (int i = 0; i < numOverrides; i++) { 1358d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount String fromName = mNameOverrides.keyAt(i); 1359d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount overriddenViews.add(mStartValues.nameValues.remove(fromName)); 1360d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1361d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount for (int i = 0; i < numOverrides; i++) { 1362d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount View view = overriddenViews.get(i); 1363d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount if (view != null) { 1364d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount String toName = mNameOverrides.valueAt(i); 1365d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount mStartValues.nameValues.put(toName, view); 1366d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1367d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1368d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1369faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1370faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 137130da61d477bcb6cc7718f9516c444359352fe148George Mount static void addViewValues(TransitionValuesMaps transitionValuesMaps, 137230da61d477bcb6cc7718f9516c444359352fe148George Mount View view, TransitionValues transitionValues) { 137330da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.viewValues.put(view, transitionValues); 137430da61d477bcb6cc7718f9516c444359352fe148George Mount int id = view.getId(); 137530da61d477bcb6cc7718f9516c444359352fe148George Mount if (id >= 0) { 137630da61d477bcb6cc7718f9516c444359352fe148George Mount if (transitionValuesMaps.idValues.indexOfKey(id) >= 0) { 137730da61d477bcb6cc7718f9516c444359352fe148George Mount // Duplicate IDs cannot match by ID. 137830da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.idValues.put(id, null); 137930da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 138030da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.idValues.put(id, view); 138130da61d477bcb6cc7718f9516c444359352fe148George Mount } 138230da61d477bcb6cc7718f9516c444359352fe148George Mount } 138330da61d477bcb6cc7718f9516c444359352fe148George Mount String name = view.getViewName(); 138430da61d477bcb6cc7718f9516c444359352fe148George Mount if (name != null) { 138530da61d477bcb6cc7718f9516c444359352fe148George Mount if (transitionValuesMaps.nameValues.containsKey(name)) { 138630da61d477bcb6cc7718f9516c444359352fe148George Mount // Duplicate viewNames: cannot match by viewName. 138730da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.nameValues.put(name, null); 138830da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 138930da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.nameValues.put(name, view); 139030da61d477bcb6cc7718f9516c444359352fe148George Mount } 139130da61d477bcb6cc7718f9516c444359352fe148George Mount } 139230da61d477bcb6cc7718f9516c444359352fe148George Mount if (view.getParent() instanceof ListView) { 139330da61d477bcb6cc7718f9516c444359352fe148George Mount ListView listview = (ListView) view.getParent(); 139430da61d477bcb6cc7718f9516c444359352fe148George Mount if (listview.getAdapter().hasStableIds()) { 139530da61d477bcb6cc7718f9516c444359352fe148George Mount int position = listview.getPositionForView(view); 139630da61d477bcb6cc7718f9516c444359352fe148George Mount long itemId = listview.getItemIdAtPosition(position); 139730da61d477bcb6cc7718f9516c444359352fe148George Mount if (transitionValuesMaps.itemIdValues.indexOfKey(itemId) >= 0) { 139830da61d477bcb6cc7718f9516c444359352fe148George Mount // Duplicate item IDs: cannot match by item ID. 139930da61d477bcb6cc7718f9516c444359352fe148George Mount View alreadyMatched = transitionValuesMaps.itemIdValues.get(itemId); 140030da61d477bcb6cc7718f9516c444359352fe148George Mount if (alreadyMatched != null) { 140130da61d477bcb6cc7718f9516c444359352fe148George Mount alreadyMatched.setHasTransientState(false); 140230da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.itemIdValues.put(itemId, null); 140330da61d477bcb6cc7718f9516c444359352fe148George Mount } 140430da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 140530da61d477bcb6cc7718f9516c444359352fe148George Mount view.setHasTransientState(true); 140630da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.itemIdValues.put(itemId, view); 140730da61d477bcb6cc7718f9516c444359352fe148George Mount } 140830da61d477bcb6cc7718f9516c444359352fe148George Mount } 140930da61d477bcb6cc7718f9516c444359352fe148George Mount } 141030da61d477bcb6cc7718f9516c444359352fe148George Mount } 141130da61d477bcb6cc7718f9516c444359352fe148George Mount 1412faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1413df32aa87150768795816852c6393306893467ecaChet Haase * Clear valuesMaps for specified start/end state 1414df32aa87150768795816852c6393306893467ecaChet Haase * 1415df32aa87150768795816852c6393306893467ecaChet Haase * @param start true if the start values should be cleared, false otherwise 1416df32aa87150768795816852c6393306893467ecaChet Haase */ 1417df32aa87150768795816852c6393306893467ecaChet Haase void clearValues(boolean start) { 1418df32aa87150768795816852c6393306893467ecaChet Haase if (start) { 1419df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.viewValues.clear(); 1420df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.idValues.clear(); 1421df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.itemIdValues.clear(); 1422d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount mStartValues.nameValues.clear(); 1423df32aa87150768795816852c6393306893467ecaChet Haase } else { 1424df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.viewValues.clear(); 1425df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.idValues.clear(); 1426df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.itemIdValues.clear(); 1427d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount mEndValues.nameValues.clear(); 1428df32aa87150768795816852c6393306893467ecaChet Haase } 1429df32aa87150768795816852c6393306893467ecaChet Haase } 1430df32aa87150768795816852c6393306893467ecaChet Haase 1431df32aa87150768795816852c6393306893467ecaChet Haase /** 1432faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Recursive method which captures values for an entire view hierarchy, 1433faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * starting at some root view. Transitions without targetIDs will use this 1434faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * method to capture values for all possible views. 1435faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1436faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param view The view for which to capture values. Children of this View 1437faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will also be captured, recursively down to the leaf nodes. 1438faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param start true if values are being captured in the start scene, false 1439faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * otherwise. 1440faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1441faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private void captureHierarchy(View view, boolean start) { 1442faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view == null) { 1443faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return; 1444faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 144530da61d477bcb6cc7718f9516c444359352fe148George Mount int id = view.getId(); 1446ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdExcludes != null && mTargetIdExcludes.contains(id)) { 1447ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1448ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1449ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetExcludes != null && mTargetExcludes.contains(view)) { 1450ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1451ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1452ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes != null && view != null) { 1453ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeExcludes.size(); 1454ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 1455ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes.get(i).isInstance(view)) { 1456ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1457ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1458ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1459ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1460e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (view.getParent() instanceof ViewGroup) { 1461e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount TransitionValues values = new TransitionValues(); 1462e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount values.view = view; 1463e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (start) { 1464e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount captureStartValues(values); 1465faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1466e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount captureEndValues(values); 1467faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1468d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount capturePropagationValues(values); 1469e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (start) { 147030da61d477bcb6cc7718f9516c444359352fe148George Mount addViewValues(mStartValues, view, values); 1471faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 147230da61d477bcb6cc7718f9516c444359352fe148George Mount addViewValues(mEndValues, view, values); 1473faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1474faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1475faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view instanceof ViewGroup) { 1476ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase // Don't traverse child hierarchy if there are any child-excludes on this view 1477ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdChildExcludes != null && mTargetIdChildExcludes.contains(id)) { 1478ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1479ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1480ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetChildExcludes != null && mTargetChildExcludes.contains(view)) { 1481ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1482ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 148330da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetTypeChildExcludes != null) { 1484ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeChildExcludes.size(); 1485ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 1486ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeChildExcludes.get(i).isInstance(view)) { 1487ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1488ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1489ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1490ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1491faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ViewGroup parent = (ViewGroup) view; 1492faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < parent.getChildCount(); ++i) { 1493faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase captureHierarchy(parent.getChildAt(i), start); 1494faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1495faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1496faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1497faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1498faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 14996ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * This method can be called by transitions to get the TransitionValues for 15006ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * any particular view during the transition-playing process. This might be 15016ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * necessary, for example, to query the before/after state of related views 15026ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * for a given transition. 15036ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase */ 1504d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public TransitionValues getTransitionValues(View view, boolean start) { 15056ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (mParent != null) { 15066ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return mParent.getTransitionValues(view, start); 15076ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 15086ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValuesMaps valuesMaps = start ? mStartValues : mEndValues; 150930da61d477bcb6cc7718f9516c444359352fe148George Mount return valuesMaps.viewValues.get(view); 15106ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 15116ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 15126ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase /** 1513199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Pauses this transition, sending out calls to {@link 1514199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * TransitionListener#onTransitionPause(Transition)} to all listeners 1515199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * and pausing all running animators started by this transition. 1516199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1517199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @hide 1518199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1519cf68aad3164303df59b2a669d186a94533c9c743George Mount public void pause(View sceneRoot) { 1520a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (!mEnded) { 1521a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1522a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numOldAnims = runningAnimators.size(); 1523cf68aad3164303df59b2a669d186a94533c9c743George Mount WindowId windowId = sceneRoot.getWindowId(); 1524a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1525cf68aad3164303df59b2a669d186a94533c9c743George Mount AnimationInfo info = runningAnimators.valueAt(i); 1526cf68aad3164303df59b2a669d186a94533c9c743George Mount if (info.view != null && windowId.equals(info.windowId)) { 1527cf68aad3164303df59b2a669d186a94533c9c743George Mount Animator anim = runningAnimators.keyAt(i); 1528cf68aad3164303df59b2a669d186a94533c9c743George Mount anim.pause(); 1529cf68aad3164303df59b2a669d186a94533c9c743George Mount } 1530a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1531a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (mListeners != null && mListeners.size() > 0) { 1532a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayList<TransitionListener> tmpListeners = 1533a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1534a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numListeners = tmpListeners.size(); 1535a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = 0; i < numListeners; ++i) { 1536a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase tmpListeners.get(i).onTransitionPause(this); 1537a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1538199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1539a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mPaused = true; 1540199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1541199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1542199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1543199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1544199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Resumes this transition, sending out calls to {@link 1545199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * TransitionListener#onTransitionPause(Transition)} to all listeners 1546199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * and pausing all running animators started by this transition. 1547199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1548199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @hide 1549199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1550cf68aad3164303df59b2a669d186a94533c9c743George Mount public void resume(View sceneRoot) { 1551199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (mPaused) { 1552a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (!mEnded) { 1553a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1554a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numOldAnims = runningAnimators.size(); 1555cf68aad3164303df59b2a669d186a94533c9c743George Mount WindowId windowId = sceneRoot.getWindowId(); 1556a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1557cf68aad3164303df59b2a669d186a94533c9c743George Mount AnimationInfo info = runningAnimators.valueAt(i); 1558cf68aad3164303df59b2a669d186a94533c9c743George Mount if (info.view != null && windowId.equals(info.windowId)) { 1559cf68aad3164303df59b2a669d186a94533c9c743George Mount Animator anim = runningAnimators.keyAt(i); 1560cf68aad3164303df59b2a669d186a94533c9c743George Mount anim.resume(); 1561cf68aad3164303df59b2a669d186a94533c9c743George Mount } 1562a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1563a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (mListeners != null && mListeners.size() > 0) { 1564a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayList<TransitionListener> tmpListeners = 1565a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1566a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numListeners = tmpListeners.size(); 1567a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = 0; i < numListeners; ++i) { 1568a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase tmpListeners.get(i).onTransitionResume(this); 1569a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1570199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1571199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1572199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mPaused = false; 1573199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1574199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1575199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1576199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1577faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Called by TransitionManager to play the transition. This calls 1578d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimators() to set things up and create all of the animations and then 15792ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * runAnimations() to actually start the animations. 1580faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 15816ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase void playTransition(ViewGroup sceneRoot) { 1582199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1583199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase int numOldAnims = runningAnimators.size(); 1584199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1585199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Animator anim = runningAnimators.keyAt(i); 1586199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (anim != null) { 1587199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase AnimationInfo oldInfo = runningAnimators.get(anim); 158858ad12208afcf9fdce735dead8449c4db375344dChet Haase if (oldInfo != null && oldInfo.view != null && 158958ad12208afcf9fdce735dead8449c4db375344dChet Haase oldInfo.view.getContext() == sceneRoot.getContext()) { 1590199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase boolean cancel = false; 1591199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues oldValues = oldInfo.values; 1592199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase View oldView = oldInfo.view; 159330da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues newValues = mEndValues.viewValues.get(oldView); 1594af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (oldValues != null) { 1595af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase // if oldValues null, then transition didn't care to stash values, 1596af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase // and won't get canceled 159723c61f6bc57a611d97d333bce0d8fe00ab81af4cChet Haase if (newValues != null) { 1598af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase for (String key : oldValues.values.keySet()) { 1599af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase Object oldValue = oldValues.values.get(key); 1600af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase Object newValue = newValues.values.get(key); 1601af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (oldValue != null && newValue != null && 1602af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase !oldValue.equals(newValue)) { 1603af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase cancel = true; 1604af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase if (DBG) { 1605af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase Log.d(LOG_TAG, "Transition.playTransition: " + 1606af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase "oldValue != newValue for " + key + 1607af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase ": old, new = " + oldValue + ", " + newValue); 1608af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase } 1609af78bdd615ecd5ce9d41a6160ce9f53fa269b119Chet Haase break; 1610199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1611199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1612199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1613199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1614199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (cancel) { 1615199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (anim.isRunning() || anim.isStarted()) { 1616199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 1617199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Log.d(LOG_TAG, "Canceling anim " + anim); 1618199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1619199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase anim.cancel(); 1620199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } else { 1621199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 1622199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Log.d(LOG_TAG, "removing anim from info list: " + anim); 1623199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1624199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.remove(anim); 1625199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1626199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1627199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1628199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1629199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1630199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1631d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase createAnimators(sceneRoot, mStartValues, mEndValues); 1632d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase runAnimators(); 1633faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1634faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1635faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1636faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This is a utility method used by subclasses to handle standard parts of 1637faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * setting up and running an Animator: it sets the {@link #getDuration() 1638faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * duration} and the {@link #getStartDelay() startDelay}, starts the 1639199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation, and, when the animator ends, calls {@link #end()}. 1640faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1641faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param animator The Animator to be run during this transition. 1642faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1643faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1644faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1645faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase protected void animate(Animator animator) { 1646faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // TODO: maybe pass auto-end as a boolean parameter? 1647faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (animator == null) { 1648199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 1649faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1650faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getDuration() >= 0) { 1651faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.setDuration(getDuration()); 1652faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1653faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getStartDelay() >= 0) { 1654d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount animator.setStartDelay(getStartDelay() + animator.getStartDelay()); 1655faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1656faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getInterpolator() != null) { 1657faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.setInterpolator(getInterpolator()); 1658faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1659faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.addListener(new AnimatorListenerAdapter() { 1660faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1661faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onAnimationEnd(Animator animation) { 1662199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 1663faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animation.removeListener(this); 1664faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1665faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase }); 1666faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.start(); 1667faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1668faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1669faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1670faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1671faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method is called automatically by the transition and 1672d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet classes prior to a Transition subclass starting; 1673faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * subclasses should not need to call it directly. 1674faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1675faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1676faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1677199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void start() { 1678faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mNumInstances == 0) { 1679faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1680faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1681faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1682faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1683faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1684faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionStart(this); 1685faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1686faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1687a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mEnded = false; 1688faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1689faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mNumInstances++; 1690faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1691faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1692faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1693faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method is called automatically by the Transition and 1694d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet classes when a transition finishes, either because 1695faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * a transition did nothing (returned a null Animator from 1696d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link Transition#createAnimator(ViewGroup, TransitionValues, 1697faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * TransitionValues)}) or because the transition returned a valid 1698199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Animator and end() was called in the onAnimationEnd() 1699faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * callback of the AnimatorListener. 1700faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1701faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1702faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1703199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void end() { 1704faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase --mNumInstances; 1705faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mNumInstances == 0) { 1706faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1707faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1708faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1709faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1710faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1711faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionEnd(this); 1712faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1713faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 17146ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < mStartValues.itemIdValues.size(); ++i) { 171530da61d477bcb6cc7718f9516c444359352fe148George Mount View view = mStartValues.itemIdValues.valueAt(i); 171630da61d477bcb6cc7718f9516c444359352fe148George Mount if (view != null) { 171730da61d477bcb6cc7718f9516c444359352fe148George Mount view.setHasTransientState(false); 1718faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1719faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 17206ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < mEndValues.itemIdValues.size(); ++i) { 172130da61d477bcb6cc7718f9516c444359352fe148George Mount View view = mEndValues.itemIdValues.valueAt(i); 172230da61d477bcb6cc7718f9516c444359352fe148George Mount if (view != null) { 172330da61d477bcb6cc7718f9516c444359352fe148George Mount view.setHasTransientState(false); 1724faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1725faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1726a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mEnded = true; 1727faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1728faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1729faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1730faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1731faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method cancels a transition that is currently running. 1732d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 1733d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @hide 1734faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1735199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void cancel() { 1736e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase int numAnimators = mCurrentAnimators.size(); 173725a738fb257aacfc87d3363a834ed6e0b050c3b1Chet Haase for (int i = numAnimators - 1; i >= 0; i--) { 1738e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase Animator animator = mCurrentAnimators.get(i); 1739e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animator.cancel(); 1740e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 1741faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1742faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1743faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1744faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1745faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1746faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionCancel(this); 1747faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1748faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1749faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1750faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1751faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1752faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Adds a listener to the set of listeners that are sent events through the 1753faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * life of an animation, such as start, repeat, and end. 1754faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1755faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param listener the listener to be added to the current set of listeners 1756faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * for this animation. 1757d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 1758faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1759d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition addListener(TransitionListener listener) { 1760faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners == null) { 1761faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners = new ArrayList<TransitionListener>(); 1762faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1763faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners.add(listener); 1764d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1765faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1766faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1767faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1768faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Removes a listener from the set listening to this animation. 1769faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1770faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param listener the listener to be removed from the current set of 1771faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listeners for this transition. 1772d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 1773faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1774d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition removeListener(TransitionListener listener) { 1775faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners == null) { 1776d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1777faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1778faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners.remove(listener); 1779faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners.size() == 0) { 1780faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners = null; 1781faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1782d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1783faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1784faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1785d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1786d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Sets the callback to use to find the epicenter of a Transition. A null value indicates 1787dc21d3b2804c24fe29ec860796d11185901364c4George Mount * that there is no epicenter in the Transition and onGetEpicenter() will return null. 1788d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Transitions like {@link android.transition.Explode} use a point or Rect to orient 1789d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the direction of travel. This is called the epicenter of the Transition and is 1790d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * typically centered on a touched View. The 1791d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} allows a Transition to 1792d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * dynamically retrieve the epicenter during a Transition. 1793d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param epicenterCallback The callback to use to find the epicenter of the Transition. 1794d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1795d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void setEpicenterCallback(EpicenterCallback epicenterCallback) { 1796d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mEpicenterCallback = epicenterCallback; 1797d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1798d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1799d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1800d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Returns the callback used to find the epicenter of the Transition. 1801d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Transitions like {@link android.transition.Explode} use a point or Rect to orient 1802d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the direction of travel. This is called the epicenter of the Transition and is 1803d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * typically centered on a touched View. The 1804d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} allows a Transition to 1805d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * dynamically retrieve the epicenter during a Transition. 1806d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return the callback used to find the epicenter of the Transition. 1807d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1808d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public EpicenterCallback getEpicenterCallback() { 1809d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return mEpicenterCallback; 1810d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1811d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1812d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1813d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Returns the epicenter as specified by the 1814d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists. 1815d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return the epicenter as specified by the 1816d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists. 1817d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback) 1818d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1819d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public Rect getEpicenter() { 1820d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (mEpicenterCallback == null) { 1821d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return null; 1822d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1823dc21d3b2804c24fe29ec860796d11185901364c4George Mount return mEpicenterCallback.onGetEpicenter(this); 1824d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1825d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1826d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1827d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Sets the method for determining Animator start delays. 1828d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * When a Transition affects several Views like {@link android.transition.Explode} or 1829d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect 1830d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * such that the Animator start delay depends on position of the View. The 1831d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * TransitionPropagation specifies how the start delays are calculated. 1832d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param transitionPropagation The class used to determine the start delay of 1833d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Animators created by this Transition. A null value 1834d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * indicates that no delay should be used. 1835d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1836d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void setPropagation(TransitionPropagation transitionPropagation) { 1837d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mPropagation = transitionPropagation; 1838d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1839d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1840d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1841d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Returns the {@link android.transition.TransitionPropagation} used to calculate Animator start 1842d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * delays. 1843d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * When a Transition affects several Views like {@link android.transition.Explode} or 1844d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect 1845d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * such that the Animator start delay depends on position of the View. The 1846d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * TransitionPropagation specifies how the start delays are calculated. 1847d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return the {@link android.transition.TransitionPropagation} used to calculate Animator start 1848d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * delays. This is null by default. 1849d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1850d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public TransitionPropagation getPropagation() { 1851d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return mPropagation; 1852d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1853d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1854d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1855d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Captures TransitionPropagation values for the given view and the 1856d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * hierarchy underneath it. 1857d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1858d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount void capturePropagationValues(TransitionValues transitionValues) { 185931a217290cf376d0573fc36e21c8940987485019George Mount if (mPropagation != null && !transitionValues.values.isEmpty()) { 1860d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount String[] propertyNames = mPropagation.getPropagationProperties(); 1861d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (propertyNames == null) { 1862d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return; 1863d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1864d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount boolean containsAll = true; 1865d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount for (int i = 0; i < propertyNames.length; i++) { 1866d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (!transitionValues.values.containsKey(propertyNames[i])) { 1867d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount containsAll = false; 1868d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount break; 1869d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1870d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1871d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (!containsAll) { 1872d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mPropagation.captureValues(transitionValues); 1873d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1874d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1875d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1876d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1877d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Transition setSceneRoot(ViewGroup sceneRoot) { 18786ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mSceneRoot = sceneRoot; 1879d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 18806ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 18816ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 1882b7a7fc9d233bad507ce893882352618b13647058Chet Haase void setCanRemoveViews(boolean canRemoveViews) { 1883b7a7fc9d233bad507ce893882352618b13647058Chet Haase mCanRemoveViews = canRemoveViews; 1884b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 1885b7a7fc9d233bad507ce893882352618b13647058Chet Haase 18860a778eda690a66173733a63622886e888d405c45George Mount public boolean canRemoveViews() { 18870a778eda690a66173733a63622886e888d405c45George Mount return mCanRemoveViews; 18880a778eda690a66173733a63622886e888d405c45George Mount } 18890a778eda690a66173733a63622886e888d405c45George Mount 1890d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount /** 1891d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount * Sets the shared element names -- a mapping from a name at the start state to 1892d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount * a different name at the end state. 1893d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount * @hide 1894d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount */ 1895d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount public void setNameOverrides(ArrayMap<String, String> overrides) { 1896d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount mNameOverrides = overrides; 1897d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1898d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount 1899d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount /** @hide */ 1900d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount public ArrayMap<String, String> getNameOverrides() { 1901d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount return mNameOverrides; 1902d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1903d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount 1904faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1905faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public String toString() { 1906faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return toString(""); 1907faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1908faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 19096ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase @Override 19106ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase public Transition clone() { 19116ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase Transition clone = null; 19126ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase try { 19136ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase clone = (Transition) super.clone(); 1914199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase clone.mAnimators = new ArrayList<Animator>(); 19157660d121b2ef21164ed33e6091e5dd50f5d0f939Chet Haase clone.mStartValues = new TransitionValuesMaps(); 19167660d121b2ef21164ed33e6091e5dd50f5d0f939Chet Haase clone.mEndValues = new TransitionValuesMaps(); 19176ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } catch (CloneNotSupportedException e) {} 19186ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 19196ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return clone; 19206ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 19216ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 1922199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1923199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the name of this Transition. This name is used internally to distinguish 1924199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * between different transitions to determine when interrupting transitions overlap. 1925d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * For example, a ChangeBounds running on the same target view as another ChangeBounds 1926d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should determine whether the old transition is animating to different end values 1927d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * and should be canceled in favor of the new transition. 1928199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1929199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * <p>By default, a Transition's name is simply the value of {@link Class#getName()}, 1930199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * but subclasses are free to override and return something different.</p> 1931199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1932199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return The name of this transition. 1933199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1934199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public String getName() { 1935199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return mName; 1936199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1937199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1938faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase String toString(String indent) { 1939faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase String result = indent + getClass().getSimpleName() + "@" + 1940faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase Integer.toHexString(hashCode()) + ": "; 1941c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mDuration != -1) { 1942c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "dur(" + mDuration + ") "; 1943c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1944c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mStartDelay != -1) { 1945c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "dly(" + mStartDelay + ") "; 1946c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1947c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mInterpolator != null) { 1948c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "interp(" + mInterpolator + ") "; 1949c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1950d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0 || mTargets.size() > 0) { 1951c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "tgts("; 1952d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0) { 1953d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargetIds.size(); ++i) { 1954c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (i > 0) { 1955c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ", "; 1956c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1957d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase result += mTargetIds.get(i); 1958faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1959faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1960d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargets.size() > 0) { 1961d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargets.size(); ++i) { 1962c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (i > 0) { 1963c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ", "; 1964c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 1965d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase result += mTargets.get(i); 1966faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1967faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1968c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ")"; 1969faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1970faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return result; 1971faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1972faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1973faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1974faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * A transition listener receives notifications from a transition. 1975199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notifications indicate transition lifecycle events. 1976faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1977faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public static interface TransitionListener { 1978faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1979faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the start of the transition. 1980faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1981faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The started transition. 1982faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1983faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionStart(Transition transition); 1984faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1985faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1986faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the end of the transition. Canceled transitions 1987faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will always notify listeners of both the cancellation and end 1988199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * events. That is, {@link #onTransitionEnd(Transition)} is always called, 1989faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * regardless of whether the transition was canceled or played 1990faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * through to completion. 1991faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1992faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The transition which reached its end. 1993faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1994faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionEnd(Transition transition); 1995faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1996faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1997faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the cancellation of the transition. 1998d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that cancel may be called by a parent {@link TransitionSet} on 1999199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 2000199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state on target objects which was set at 2001d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 2002d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimator()} time. 2003faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 2004faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The transition which was canceled. 2005faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 2006faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionCancel(Transition transition); 2007199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2008199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 2009199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notification when a transition is paused. 2010d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that createAnimator() may be called by a parent {@link TransitionSet} on 2011199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 2012199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state on target objects which was set at 2013d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 2014d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimator()} time. 2015199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 2016199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @param transition The transition which was paused. 2017199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 2018199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase void onTransitionPause(Transition transition); 2019199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2020199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 2021199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notification when a transition is resumed. 2022d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that resume() may be called by a parent {@link TransitionSet} on 2023199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 2024199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state which may have changed in an earlier call 2025199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * to {@link #onTransitionPause(Transition)}. 2026199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 2027199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @param transition The transition which was resumed. 2028199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 2029199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase void onTransitionResume(Transition transition); 2030faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2031faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2032faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 2033faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Utility adapter class to avoid having to override all three methods 2034faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * whenever someone just wants to listen for a single event. 2035faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 2036faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 2037faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * */ 2038faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public static class TransitionListenerAdapter implements TransitionListener { 2039faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 2040faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionStart(Transition transition) { 2041faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2042faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2043faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 2044faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionEnd(Transition transition) { 2045faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2046faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2047faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 2048faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionCancel(Transition transition) { 2049faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2050199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2051199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase @Override 2052199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void onTransitionPause(Transition transition) { 2053199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 2054199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2055199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase @Override 2056199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void onTransitionResume(Transition transition) { 2057199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 2058faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2059faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2060199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 2061199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Holds information about each animator used when a new transition starts 2062199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * while other transitions are still running to determine whether a running 2063199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation should be canceled or a new animation noop'd. The structure holds 2064199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * information about the state that an animation is going to, to be compared to 2065199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * end state of a new animation. 20660a778eda690a66173733a63622886e888d405c45George Mount * @hide 2067199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 20680a778eda690a66173733a63622886e888d405c45George Mount public static class AnimationInfo { 20690a778eda690a66173733a63622886e888d405c45George Mount public View view; 2070199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase String name; 2071199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues values; 2072cf68aad3164303df59b2a669d186a94533c9c743George Mount WindowId windowId; 2073199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2074cf68aad3164303df59b2a669d186a94533c9c743George Mount AnimationInfo(View view, String name, WindowId windowId, TransitionValues values) { 2075199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.view = view; 2076199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.name = name; 2077199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.values = values; 2078cf68aad3164303df59b2a669d186a94533c9c743George Mount this.windowId = windowId; 2079199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 2080199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 2081ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 2082ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 2083ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility class for managing typed ArrayLists efficiently. In particular, this 2084ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * can be useful for lists that we don't expect to be used often (eg, the exclude 2085ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * lists), so we'd like to keep them nulled out by default. This causes the code to 2086ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * become tedious, with constant null checks, code to allocate when necessary, 2087ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * and code to null out the reference when the list is empty. This class encapsulates 2088ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * all of that functionality into simple add()/remove() methods which perform the 2089ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * necessary checks, allocation/null-out as appropriate, and return the 2090ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * resulting list. 2091ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 2092ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private static class ArrayListManager { 2093ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 2094ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 2095ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Add the specified item to the list, returning the resulting list. 2096ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * The returned list can either the be same list passed in or, if that 2097ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list was null, the new list that was created. 2098ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 2099ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Note that the list holds unique items; if the item already exists in the 2100ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list, the list is not modified. 2101ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 2102ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase static <T> ArrayList<T> add(ArrayList<T> list, T item) { 2103ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list == null) { 2104ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = new ArrayList<T>(); 2105ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2106ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (!list.contains(item)) { 2107ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list.add(item); 2108ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2109ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 2110ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2111ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 2112ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 2113ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Remove the specified item from the list, returning the resulting list. 2114ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * The returned list can either the be same list passed in or, if that 2115ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list becomes empty as a result of the remove(), the new list was created. 2116ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 2117ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase static <T> ArrayList<T> remove(ArrayList<T> list, T item) { 2118ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list != null) { 2119ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list.remove(item); 2120ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list.isEmpty()) { 2121ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = null; 2122ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2123ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2124ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 2125ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2126ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2127ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 2128d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 2129d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Class to get the epicenter of Transition. Use 2130d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #setEpicenterCallback(android.transition.Transition.EpicenterCallback)} to 2131d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * set the callback used to calculate the epicenter of the Transition. Override 2132d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #getEpicenter()} to return the rectangular region in screen coordinates of 2133d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the epicenter of the transition. 2134d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback) 2135d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 2136d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public static abstract class EpicenterCallback { 2137d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 2138d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 2139d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Implementers must override to return the epicenter of the Transition in screen 2140d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * coordinates. Transitions like {@link android.transition.Explode} depend upon 2141d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * an epicenter for the Transition. In Explode, Views move toward or away from the 2142d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * center of the epicenter Rect along the vector between the epicenter and the center 2143d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * of the View appearing and disappearing. Some Transitions, such as 2144d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Fade} pay no attention to the epicenter. 2145d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 2146d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param transition The transition for which the epicenter applies. 2147d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return The Rect region of the epicenter of <code>transition</code> or null if 2148d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * there is no epicenter. 2149d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 2150dc21d3b2804c24fe29ec860796d11185901364c4George Mount public abstract Rect onGetEpicenter(Transition transition); 2151d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2152faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase} 2153