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; 22ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.content.Context; 23ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.content.res.TypedArray; 24ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.graphics.Path; 25d6107a3170df61d9e776fcd5666acfc9135c6f16George Mountimport android.graphics.Rect; 2608735185f8105710e18ad02297461bec9268e514Chet Haaseimport android.util.ArrayMap; 27ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.util.AttributeSet; 28c43524f3869cc0d36974fce61986017093f2ecd2Chet Haaseimport android.util.Log; 29faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.util.LongSparseArray; 30faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.util.SparseArray; 31d6107a3170df61d9e776fcd5666acfc9135c6f16George Mountimport android.util.SparseLongArray; 32ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.view.InflateException; 33faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.SurfaceView; 34faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.TextureView; 35faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.View; 36faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewGroup; 37faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewOverlay; 38cf68aad3164303df59b2a669d186a94533c9c743George Mountimport android.view.WindowId; 39ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport android.view.animation.AnimationUtils; 40faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.widget.ListView; 41ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haaseimport android.widget.Spinner; 42faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 43faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport java.util.ArrayList; 44d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haaseimport java.util.List; 45ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport java.util.StringTokenizer; 46ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 47ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mountimport com.android.internal.R; 48faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 49faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/** 50faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * A Transition holds information about animations that will be run on its 51faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * targets during a scene change. Subclasses of this abstract class may 52d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * choreograph several child transitions ({@link TransitionSet} or they may 53faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * perform custom animations themselves. Any Transition has two main jobs: 54faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (1) capture property values, and (2) play animations based on changes to 55faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * captured property values. A custom transition knows what property values 56faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on View objects are of interest to it, and also knows how to animate 57faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes to those values. For example, the {@link Fade} transition tracks 58faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes to visibility-related properties and is able to construct and run 59faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animations that fade items in or out based on changes to those properties. 60faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 61faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>Note: Transitions may not work correctly with either {@link SurfaceView} 62faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * or {@link TextureView}, due to the way that these views are displayed 63faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on the screen. For SurfaceView, the problem is that the view is updated from 64faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * a non-UI thread, so changes to the view due to transitions (such as moving 65faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * and resizing the view) may be out of sync with the display inside those bounds. 66faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * TextureView is more compatible with transitions in general, but some 67d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * specific transitions (such as {@link Fade}) may not be compatible 68faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * with TextureView because they rely on {@link ViewOverlay} functionality, 69faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * which does not currently work with TextureView.</p> 70d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 71d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Transitions can be declared in XML resource files inside the <code>res/transition</code> 72d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * directory. Transition resources consist of a tag name for one of the Transition 73d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * subclasses along with attributes to define some of the attributes of that transition. 74d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * For example, here is a minimal resource file that declares a {@link ChangeBounds} transition: 75d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 76d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@sample development/samples/ApiDemos/res/transition/changebounds.xml ChangeBounds} 77d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 78608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * <p>This TransitionSet contains {@link android.transition.Explode} for visibility, 79608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * {@link android.transition.ChangeBounds}, {@link android.transition.ChangeTransform}, 80990205eada00ad3e575761d19607bb03e12f9aa3George Mount * and {@link android.transition.ChangeClipBounds} and 81990205eada00ad3e575761d19607bb03e12f9aa3George Mount * {@link android.transition.ChangeImageTransform}:</p> 82d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 83608b87d9e57b71a86374a439bf5c3febd1e142f2George Mount * {@sample development/samples/ApiDemos/res/transition/explode_move_together.xml MultipleTransform} 84d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 8544d663849481576fb649aeb6234086406ced75f1George Mount * <p>Custom transition classes may be instantiated with a <code>transition</code> tag:</p> 8644d663849481576fb649aeb6234086406ced75f1George Mount * <pre><transition class="my.app.transition.CustomTransition"/></pre> 87b592d845147f051613fb62896b4e893015f8c413George Mount * <p>Custom transition classes loaded from XML should have a public constructor taking 88b592d845147f051613fb62896b4e893015f8c413George Mount * a {@link android.content.Context} and {@link android.util.AttributeSet}.</p> 8944d663849481576fb649aeb6234086406ced75f1George Mount * 90d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Note that attributes for the transition are not required, just as they are 91d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * optional when declared in code; Transitions created from XML resources will use 92d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * the same defaults as their code-created equivalents. Here is a slightly more 93d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * elaborate example which declares a {@link TransitionSet} transition with 94d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link ChangeBounds} and {@link Fade} child transitions:</p> 95d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 96d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@sample 97d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * development/samples/ApiDemos/res/transition/changebounds_fadeout_sequential.xml TransitionSet} 98d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 99d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>In this example, the transitionOrdering attribute is used on the TransitionSet 100d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * object to change from the default {@link TransitionSet#ORDERING_TOGETHER} behavior 101d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * to be {@link TransitionSet#ORDERING_SEQUENTIAL} instead. Also, the {@link Fade} 102d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition uses a fadingMode of {@link Fade#OUT} instead of the default 103d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * out-in behavior. Finally, note the use of the <code>targets</code> sub-tag, which 104d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * takes a set of {@link android.R.styleable#TransitionTarget target} tags, each 105a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * of which lists a specific <code>targetId</code>, <code>targetClass</code>, 1060a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * <code>targetName</code>, <code>excludeId</code>, <code>excludeClass</code>, or 1070a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * <code>excludeName</code>, which this transition acts upon. 108d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Use of targets is optional, but can be used to either limit the time spent checking 109d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * attributes on unchanging views, or limiting the types of animations run on specific views. 110d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * In this case, we know that only the <code>grayscaleContainer</code> will be 111d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * disappearing, so we choose to limit the {@link Fade} transition to only that view.</p> 112d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 113d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Further information on XML resource descriptions for transitions can be found for 114d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link android.R.styleable#Transition}, {@link android.R.styleable#TransitionSet}, 115c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu * {@link android.R.styleable#TransitionTarget}, {@link android.R.styleable#Fade}, 116c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu * {@link android.R.styleable#Slide}, and {@link android.R.styleable#ChangeTransform}. 117d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 118faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1196ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haasepublic abstract class Transition implements Cloneable { 120faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 121faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private static final String LOG_TAG = "Transition"; 122faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase static final boolean DBG = false; 123faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1247b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 1257b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * With {@link #setMatchOrder(int...)}, chooses to match by View instance. 1267b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 1277b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount public static final int MATCH_INSTANCE = 0x1; 1287b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static final int MATCH_FIRST = MATCH_INSTANCE; 1297b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 1307b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 1317b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * With {@link #setMatchOrder(int...)}, chooses to match by 1320a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * {@link android.view.View#getTransitionName()}. Null names will not be matched. 1337b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 1340a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount public static final int MATCH_NAME = 0x2; 1357b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 1367b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 1377b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * With {@link #setMatchOrder(int...)}, chooses to match by 1387b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * {@link android.view.View#getId()}. Negative IDs will not be matched. 1397b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 1407b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount public static final int MATCH_ID = 0x3; 1417b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 1427b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 1437b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * With {@link #setMatchOrder(int...)}, chooses to match by the {@link android.widget.Adapter} 1447b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * item id. When {@link android.widget.Adapter#hasStableIds()} returns false, no match 1457b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * will be made for items. 1467b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 1477b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount public static final int MATCH_ITEM_ID = 0x4; 1487b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 1497b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static final int MATCH_LAST = MATCH_ITEM_ID; 1507b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 151ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount private static final String MATCH_INSTANCE_STR = "instance"; 152ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount private static final String MATCH_NAME_STR = "name"; 153ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount /** To be removed before L release */ 154ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount private static final String MATCH_VIEW_NAME_STR = "viewName"; 155ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount private static final String MATCH_ID_STR = "id"; 156ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount private static final String MATCH_ITEM_ID_STR = "itemId"; 157ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 1587b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static final int[] DEFAULT_MATCH_ORDER = { 1590a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount MATCH_NAME, 1607b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount MATCH_INSTANCE, 1617b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount MATCH_ID, 1627b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount MATCH_ITEM_ID, 1637b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount }; 1647b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 165ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount private static final PathMotion STRAIGHT_PATH_MOTION = new PathMotion() { 166ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount @Override 167ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount public Path getPath(float startX, float startY, float endX, float endY) { 168ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount Path path = new Path(); 169ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount path.moveTo(startX, startY); 170ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount path.lineTo(endX, endY); 171ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount return path; 172ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 173ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount }; 174ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 175199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private String mName = getClass().getName(); 176199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 177faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long mStartDelay = -1; 178faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase long mDuration = -1; 179faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TimeInterpolator mInterpolator = null; 180d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase ArrayList<Integer> mTargetIds = new ArrayList<Integer>(); 181d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase ArrayList<View> mTargets = new ArrayList<View>(); 18230da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<String> mTargetNames = null; 18330da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<Class> mTargetTypes = null; 184ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Integer> mTargetIdExcludes = null; 185ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<View> mTargetExcludes = null; 186ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Class> mTargetTypeExcludes = null; 18730da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayList<String> mTargetNameExcludes = null; 188ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Integer> mTargetIdChildExcludes = null; 189ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<View> mTargetChildExcludes = null; 190ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase ArrayList<Class> mTargetTypeChildExcludes = null; 1916ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private TransitionValuesMaps mStartValues = new TransitionValuesMaps(); 1926ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase private TransitionValuesMaps mEndValues = new TransitionValuesMaps(); 193d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase TransitionSet mParent = null; 1947b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private int[] mMatchOrder = DEFAULT_MATCH_ORDER; 1954d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount ArrayList<TransitionValues> mStartValuesList; // only valid after playTransition starts 1964d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount ArrayList<TransitionValues> mEndValuesList; // only valid after playTransitions starts 1976ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 198199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Per-animator information used for later canceling when future transitions overlap 199199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private static ThreadLocal<ArrayMap<Animator, AnimationInfo>> sRunningAnimators = 200199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase new ThreadLocal<ArrayMap<Animator, AnimationInfo>>(); 201199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 202d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // Scene Root is set at createAnimator() time in the cloned Transition 2036ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase ViewGroup mSceneRoot = null; 2046ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 205b7a7fc9d233bad507ce893882352618b13647058Chet Haase // Whether removing views from their parent is possible. This is only for views 206b7a7fc9d233bad507ce893882352618b13647058Chet Haase // in the start scene, which are no longer in the view hierarchy. This property 207b7a7fc9d233bad507ce893882352618b13647058Chet Haase // is determined by whether the previous Scene was created from a layout 208b7a7fc9d233bad507ce893882352618b13647058Chet Haase // resource, and thus the views from the exited scene are going away anyway 209b7a7fc9d233bad507ce893882352618b13647058Chet Haase // and can be removed as necessary to achieve a particular effect, such as 210b7a7fc9d233bad507ce893882352618b13647058Chet Haase // removing them from parents to add them to overlays. 211b7a7fc9d233bad507ce893882352618b13647058Chet Haase boolean mCanRemoveViews = false; 212b7a7fc9d233bad507ce893882352618b13647058Chet Haase 213e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // Track all animators in use in case the transition gets canceled and needs to 214e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // cancel running animators 215e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase private ArrayList<Animator> mCurrentAnimators = new ArrayList<Animator>(); 216e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase 217faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // Number of per-target instances of this Transition currently running. This count is 218199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // determined by calls to start() and end() 219faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int mNumInstances = 0; 220faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 221199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase // Whether this transition is currently paused, due to a call to pause() 222199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase boolean mPaused = false; 223c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase 224a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase // Whether this transition has ended. Used to avoid pause/resume on transitions 225a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase // that have completed 226a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase private boolean mEnded = false; 227a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase 228c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase // The set of listeners to be sent transition lifecycle events. 229faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> mListeners = null; 230faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 231d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // The set of animators collected from calls to createAnimator(), 232d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // to be run in runAnimators() 233199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayList<Animator> mAnimators = new ArrayList<Animator>(); 234c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase 235d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // The function for calculating the Animation start delay. 236d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount TransitionPropagation mPropagation; 237d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 238d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // The rectangular region for Transitions like Explode and TransitionPropagations 239d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount // like CircularPropagation 240d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount EpicenterCallback mEpicenterCallback; 241d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 242d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount // For Fragment shared element transitions, linking views explicitly by mismatching 2430a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount // transitionNames. 244d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount ArrayMap<String, String> mNameOverrides; 245d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount 246ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount // The function used to interpolate along two-dimensional points. Typically used 247ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount // for adding curves to x/y View motion. 248ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount private PathMotion mPathMotion = STRAIGHT_PATH_MOTION; 249ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 250faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 251faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Constructs a Transition object with no target objects. A transition with 252faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * no targets defaults to running on all target objects in the scene hierarchy 253d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * (if the transition is not contained in a TransitionSet), or all target 254d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * objects passed down from its parent (if it is in a TransitionSet). 255faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 256faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public Transition() {} 257faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 258faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 259ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * Perform inflation from XML and apply a class-specific base style from a 260ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * theme attribute or style resource. This constructor of Transition allows 261ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * subclasses to use their own base style when they are inflating. 262ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * 263ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * @param context The Context the transition is running in, through which it can 264ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * access the current theme, resources, etc. 265ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * @param attrs The attributes of the XML tag that is inflating the transition. 266ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount */ 267ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount public Transition(Context context, AttributeSet attrs) { 268ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 269ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Transition); 270ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount long duration = a.getInt(R.styleable.Transition_duration, -1); 271ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount if (duration >= 0) { 272ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount setDuration(duration); 273ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 274ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount long startDelay = a.getInt(R.styleable.Transition_startDelay, -1); 275ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount if (startDelay > 0) { 276ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount setStartDelay(startDelay); 277ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 278ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount final int resID = a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0); 279ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount if (resID > 0) { 280ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount setInterpolator(AnimationUtils.loadInterpolator(context, resID)); 281ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 282ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount String matchOrder = a.getString(R.styleable.Transition_matchOrder); 283ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount if (matchOrder != null) { 284ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount setMatchOrder(parseMatchOrder(matchOrder)); 285ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 286ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount a.recycle(); 287ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 288ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 289ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount private static int[] parseMatchOrder(String matchOrderString) { 290ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount StringTokenizer st = new StringTokenizer(matchOrderString, ","); 291ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount int matches[] = new int[st.countTokens()]; 292ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount int index = 0; 293ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount while (st.hasMoreTokens()) { 294ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount String token = st.nextToken().trim(); 295ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount if (MATCH_ID_STR.equalsIgnoreCase(token)) { 296ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount matches[index] = Transition.MATCH_ID; 297ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } else if (MATCH_INSTANCE_STR.equalsIgnoreCase(token)) { 298ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount matches[index] = Transition.MATCH_INSTANCE; 299ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } else if (MATCH_NAME_STR.equalsIgnoreCase(token)) { 300ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount matches[index] = Transition.MATCH_NAME; 301ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } else if (MATCH_VIEW_NAME_STR.equalsIgnoreCase(token)) { 302ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount matches[index] = Transition.MATCH_NAME; 303ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } else if (MATCH_ITEM_ID_STR.equalsIgnoreCase(token)) { 304ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount matches[index] = Transition.MATCH_ITEM_ID; 305ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } else if (token.isEmpty()) { 306ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount int[] smallerMatches = new int[matches.length - 1]; 307ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount System.arraycopy(matches, 0, smallerMatches, 0, index); 308ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount matches = smallerMatches; 309ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount index--; 310ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } else { 311ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount throw new InflateException("Unknown match type in matchOrder: '" + token + "'"); 312ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 313ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount index++; 314ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 315ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount return matches; 316ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 317ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 318ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount /** 319faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the duration of this transition. By default, there is no duration 320faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (indicated by a negative number), which means that the Animator created by 321faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition will have its own specified duration. If the duration of a 322faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that duration will override the Animator duration. 323faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 324faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param duration The length of the animation, in milliseconds. 325faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return This transition object. 326d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_duration 327faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 328faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public Transition setDuration(long duration) { 329faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mDuration = duration; 330faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 331faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 332faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 333199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 334199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the duration set on this transition. If no duration has been set, 335199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be negative, indicating that resulting animators will 336199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own durations. 337199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 338d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The duration set on this transition, in milliseconds, if one has been 339d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * set, otherwise returns a negative number. 340199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 341faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public long getDuration() { 342faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mDuration; 343faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 344faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 345faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 346faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the startDelay of this transition. By default, there is no delay 347faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * (indicated by a negative number), which means that the Animator created by 348faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition will have its own specified startDelay. If the delay of a 349faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that delay will override the Animator delay. 350faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 351faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param startDelay The length of the delay, in milliseconds. 352d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 353d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_startDelay 354faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 355d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition setStartDelay(long startDelay) { 356faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mStartDelay = startDelay; 357d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 358faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 359faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 360199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 361199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the startDelay set on this transition. If no startDelay has been set, 362199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be negative, indicating that resulting animators will 363199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own startDelays. 364199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 365d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The startDelay set on this transition, in milliseconds, if one has 366d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * been set, otherwise returns a negative number. 367199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 368faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public long getStartDelay() { 369faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mStartDelay; 370faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 371faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 372faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 373faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the interpolator of this transition. By default, the interpolator 374faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is null, which means that the Animator created by the transition 375faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will have its own specified interpolator. If the interpolator of a 376faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Transition is set, that interpolator will override the Animator interpolator. 377faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 378faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param interpolator The time interpolator used by the transition 379d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 380d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @attr ref android.R.styleable#Transition_interpolator 381faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 382d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition setInterpolator(TimeInterpolator interpolator) { 383faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mInterpolator = interpolator; 384d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 385faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 386faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 387199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 388199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the interpolator set on this transition. If no interpolator has been set, 389199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the returned value will be null, indicating that resulting animators will 390199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * retain their own interpolators. 391199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 392199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return The interpolator set on this transition, if one has been set, otherwise 393199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * returns null. 394199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 395faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public TimeInterpolator getInterpolator() { 396faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mInterpolator; 397faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 398faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 399faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 400199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the set of property names used stored in the {@link TransitionValues} 401d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * object passed into {@link #captureStartValues(TransitionValues)} that 402199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * this transition cares about for the purposes of canceling overlapping animations. 403199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * When any transition is started on a given scene root, all transitions 404199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * currently running on that same scene root are checked to see whether the 405199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * properties on which they based their animations agree with the end values of 406199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * the same properties in the new transition. If the end values are not equal, 407199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * then the old animation is canceled since the new transition will start a new 408199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation to these new values. If the values are equal, the old animation is 409199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * allowed to continue and no new animation is started for that transition. 410199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 411199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * <p>A transition does not need to override this method. However, not doing so 412199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * will mean that the cancellation logic outlined in the previous paragraph 413199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * will be skipped for that transition, possibly leading to artifacts as 414199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * old transitions and new transitions on the same targets run in parallel, 415199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animating views toward potentially different end values.</p> 416199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 417199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return An array of property names as described in the class documentation for 418199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * {@link TransitionValues}. The default implementation returns <code>null</code>. 419199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 420199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public String[] getTransitionProperties() { 421199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return null; 422199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 423199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 424199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 425d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * This method creates an animation that will be run for this transition 426d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * given the information in the startValues and endValues structures captured 427d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * earlier for the start and end scenes. Subclasses of Transition should override 428d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * this method. The method should only be called by the transition system; it is 429d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * not intended to be called from external classes. 430d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 431d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>This method is called by the transition's parent (all the way up to the 432faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * topmost Transition in the hierarchy) with the sceneRoot and start/end 4332ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * values that the transition may need to set up initial target values 4342ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * and construct an appropriate animation. For example, if an overall 435d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Transition is a {@link TransitionSet} consisting of several 436faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * child transitions in sequence, then some of the child transitions may 437faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * want to set initial values on target views prior to the overall 4382ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * Transition commencing, to put them in an appropriate state for the 439faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * delay between that start and the child Transition start time. For 440faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * example, a transition that fades an item in may wish to set the starting 441faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * alpha value to 0, to avoid it blinking in prior to the transition 442faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * actually starting the animation. This is necessary because the scene 443faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * change that triggers the Transition will automatically set the end-scene 444faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * on all target views, so a Transition that wants to animate from a 445d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * different value should set that value prior to returning from this method.</p> 446faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 447faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>Additionally, a Transition can perform logic to determine whether 448faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the transition needs to run on the given target and start/end values. 449faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * For example, a transition that resizes objects on the screen may wish 450faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * to avoid running for views which are not present in either the start 451d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * or end scenes.</p> 4522ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * 4532ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <p>If there is an animator created and returned from this method, the 4542ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * transition mechanism will apply any applicable duration, startDelay, 4552ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * and interpolator to that animation and start it. A return value of 4562ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <code>null</code> indicates that no animation should run. The default 4572ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * implementation returns null.</p> 458faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 459faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * <p>The method is called for every applicable target object, which is 460faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * stored in the {@link TransitionValues#view} field.</p> 461faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 462d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 463d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param sceneRoot The root of the transition hierarchy. 464d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param startValues The values for a specific target in the start scene. 465d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param endValues The values for the target in the end scene. 466d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return A Animator to be started at the appropriate time in the 467d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * overall transition for this scene change. A null value means no animation 468d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should be run. 469faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 470d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, 471faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues endValues) { 4722ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase return null; 473faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 474faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 475faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 4767b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * Sets the order in which Transition matches View start and end values. 4777b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * <p> 4780a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * The default behavior is to match first by {@link android.view.View#getTransitionName()}, 4797b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * then by View instance, then by {@link android.view.View#getId()} and finally 4807b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * by its item ID if it is in a direct child of ListView. The caller can 4817b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * choose to have only some or all of the values of {@link #MATCH_INSTANCE}, 4820a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * {@link #MATCH_NAME}, {@link #MATCH_ITEM_ID}, and {@link #MATCH_ID}. Only 4837b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * the match algorithms supplied will be used to determine whether Views are the 4847b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * the same in both the start and end Scene. Views that do not match will be considered 4857b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * as entering or leaving the Scene. 4867b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * </p> 4877b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * @param matches A list of zero or more of {@link #MATCH_INSTANCE}, 4880a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * {@link #MATCH_NAME}, {@link #MATCH_ITEM_ID}, and {@link #MATCH_ID}. 4897b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount * If none are provided, then the default match order will be set. 4907b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount */ 4917b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount public void setMatchOrder(int... matches) { 4927b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount if (matches == null || matches.length == 0) { 4937b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount mMatchOrder = DEFAULT_MATCH_ORDER; 4947b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } else { 4957b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount for (int i = 0; i < matches.length; i++) { 4967b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount int match = matches[i]; 4977b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount if (!isValidMatch(match)) { 4987b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount throw new IllegalArgumentException("matches contains invalid value"); 4997b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5007b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount if (alreadyContains(matches, i)) { 5017b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount throw new IllegalArgumentException("matches contains a duplicate value"); 5027b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5037b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5047b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount mMatchOrder = matches.clone(); 5057b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5067b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5077b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 5087b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static boolean isValidMatch(int match) { 5097b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount return (match >= MATCH_FIRST && match <= MATCH_LAST); 5107b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5117b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 5127b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private static boolean alreadyContains(int[] array, int searchIndex) { 5137b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount int value = array[searchIndex]; 5147b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount for (int i = 0; i < searchIndex; i++) { 5157b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount if (array[i] == value) { 5167b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount return true; 5177b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5187b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5197b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount return false; 5207b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 5217b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 5227b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount /** 5234d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * Match start/end values by View instance. Adds matched values to mStartValuesList 5244d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd. 52530da61d477bcb6cc7718f9516c444359352fe148George Mount */ 5264d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount private void matchInstances(ArrayMap<View, TransitionValues> unmatchedStart, 52730da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd) { 52830da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = unmatchedStart.size() - 1; i >= 0; i--) { 52930da61d477bcb6cc7718f9516c444359352fe148George Mount View view = unmatchedStart.keyAt(i); 53030da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues end = unmatchedEnd.remove(view); 53130da61d477bcb6cc7718f9516c444359352fe148George Mount if (end != null) { 53230da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues start = unmatchedStart.removeAt(i); 5334d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mStartValuesList.add(start); 5344d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mEndValuesList.add(end); 53530da61d477bcb6cc7718f9516c444359352fe148George Mount } 53630da61d477bcb6cc7718f9516c444359352fe148George Mount } 53730da61d477bcb6cc7718f9516c444359352fe148George Mount } 53830da61d477bcb6cc7718f9516c444359352fe148George Mount 53930da61d477bcb6cc7718f9516c444359352fe148George Mount /** 5404d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * Match start/end values by Adapter item ID. Adds matched values to mStartValuesList 5414d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using 54230da61d477bcb6cc7718f9516c444359352fe148George Mount * startItemIds and endItemIds as a guide for which Views have unique item IDs. 54330da61d477bcb6cc7718f9516c444359352fe148George Mount */ 5444d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount private void matchItemIds(ArrayMap<View, TransitionValues> unmatchedStart, 54530da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd, 54630da61d477bcb6cc7718f9516c444359352fe148George Mount LongSparseArray<View> startItemIds, LongSparseArray<View> endItemIds) { 54730da61d477bcb6cc7718f9516c444359352fe148George Mount int numStartIds = startItemIds.size(); 54830da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < numStartIds; i++) { 54930da61d477bcb6cc7718f9516c444359352fe148George Mount View startView = startItemIds.valueAt(i); 55030da61d477bcb6cc7718f9516c444359352fe148George Mount if (startView != null) { 55130da61d477bcb6cc7718f9516c444359352fe148George Mount View endView = endItemIds.get(startItemIds.keyAt(i)); 55230da61d477bcb6cc7718f9516c444359352fe148George Mount if (endView != null) { 55330da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues startValues = unmatchedStart.get(startView); 55430da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues endValues = unmatchedEnd.get(endView); 55530da61d477bcb6cc7718f9516c444359352fe148George Mount if (startValues != null && endValues != null) { 5564d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mStartValuesList.add(startValues); 5574d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mEndValuesList.add(endValues); 55830da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedStart.remove(startView); 55930da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedEnd.remove(endView); 56030da61d477bcb6cc7718f9516c444359352fe148George Mount } 56130da61d477bcb6cc7718f9516c444359352fe148George Mount } 56230da61d477bcb6cc7718f9516c444359352fe148George Mount } 56330da61d477bcb6cc7718f9516c444359352fe148George Mount } 56430da61d477bcb6cc7718f9516c444359352fe148George Mount } 56530da61d477bcb6cc7718f9516c444359352fe148George Mount 56630da61d477bcb6cc7718f9516c444359352fe148George Mount /** 5674d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * Match start/end values by Adapter view ID. Adds matched values to mStartValuesList 5684d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using 56930da61d477bcb6cc7718f9516c444359352fe148George Mount * startIds and endIds as a guide for which Views have unique IDs. 57030da61d477bcb6cc7718f9516c444359352fe148George Mount */ 5714d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount private void matchIds(ArrayMap<View, TransitionValues> unmatchedStart, 57230da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd, 57330da61d477bcb6cc7718f9516c444359352fe148George Mount SparseArray<View> startIds, SparseArray<View> endIds) { 57430da61d477bcb6cc7718f9516c444359352fe148George Mount int numStartIds = startIds.size(); 57530da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < numStartIds; i++) { 57630da61d477bcb6cc7718f9516c444359352fe148George Mount View startView = startIds.valueAt(i); 57730da61d477bcb6cc7718f9516c444359352fe148George Mount if (startView != null && isValidTarget(startView)) { 57830da61d477bcb6cc7718f9516c444359352fe148George Mount View endView = endIds.get(startIds.keyAt(i)); 57930da61d477bcb6cc7718f9516c444359352fe148George Mount if (endView != null && isValidTarget(endView)) { 58030da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues startValues = unmatchedStart.get(startView); 58130da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues endValues = unmatchedEnd.get(endView); 58230da61d477bcb6cc7718f9516c444359352fe148George Mount if (startValues != null && endValues != null) { 5834d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mStartValuesList.add(startValues); 5844d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mEndValuesList.add(endValues); 58530da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedStart.remove(startView); 58630da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedEnd.remove(endView); 58730da61d477bcb6cc7718f9516c444359352fe148George Mount } 58830da61d477bcb6cc7718f9516c444359352fe148George Mount } 58930da61d477bcb6cc7718f9516c444359352fe148George Mount } 59030da61d477bcb6cc7718f9516c444359352fe148George Mount } 59130da61d477bcb6cc7718f9516c444359352fe148George Mount } 59230da61d477bcb6cc7718f9516c444359352fe148George Mount 59330da61d477bcb6cc7718f9516c444359352fe148George Mount /** 5944d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * Match start/end values by Adapter transitionName. Adds matched values to mStartValuesList 5954d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * and mEndValuesList and removes them from unmatchedStart and unmatchedEnd, using 5960a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * startNames and endNames as a guide for which Views have unique transitionNames. 59730da61d477bcb6cc7718f9516c444359352fe148George Mount */ 5984d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount private void matchNames(ArrayMap<View, TransitionValues> unmatchedStart, 59930da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd, 60030da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<String, View> startNames, ArrayMap<String, View> endNames) { 60130da61d477bcb6cc7718f9516c444359352fe148George Mount int numStartNames = startNames.size(); 60230da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < numStartNames; i++) { 60330da61d477bcb6cc7718f9516c444359352fe148George Mount View startView = startNames.valueAt(i); 60430da61d477bcb6cc7718f9516c444359352fe148George Mount if (startView != null && isValidTarget(startView)) { 60530da61d477bcb6cc7718f9516c444359352fe148George Mount View endView = endNames.get(startNames.keyAt(i)); 60630da61d477bcb6cc7718f9516c444359352fe148George Mount if (endView != null && isValidTarget(endView)) { 60730da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues startValues = unmatchedStart.get(startView); 60830da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues endValues = unmatchedEnd.get(endView); 60930da61d477bcb6cc7718f9516c444359352fe148George Mount if (startValues != null && endValues != null) { 6104d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mStartValuesList.add(startValues); 6114d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mEndValuesList.add(endValues); 61230da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedStart.remove(startView); 61330da61d477bcb6cc7718f9516c444359352fe148George Mount unmatchedEnd.remove(endView); 61430da61d477bcb6cc7718f9516c444359352fe148George Mount } 61530da61d477bcb6cc7718f9516c444359352fe148George Mount } 61630da61d477bcb6cc7718f9516c444359352fe148George Mount } 61730da61d477bcb6cc7718f9516c444359352fe148George Mount } 61830da61d477bcb6cc7718f9516c444359352fe148George Mount } 61930da61d477bcb6cc7718f9516c444359352fe148George Mount 62030da61d477bcb6cc7718f9516c444359352fe148George Mount /** 6214d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * Adds all values from unmatchedStart and unmatchedEnd to mStartValuesList and mEndValuesList, 62230da61d477bcb6cc7718f9516c444359352fe148George Mount * assuming that there is no match between values in the list. 62330da61d477bcb6cc7718f9516c444359352fe148George Mount */ 6244d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount private void addUnmatched(ArrayMap<View, TransitionValues> unmatchedStart, 62530da61d477bcb6cc7718f9516c444359352fe148George Mount ArrayMap<View, TransitionValues> unmatchedEnd) { 62630da61d477bcb6cc7718f9516c444359352fe148George Mount // Views that only exist in the start Scene 62730da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < unmatchedStart.size(); i++) { 6284d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mStartValuesList.add(unmatchedStart.valueAt(i)); 6294d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mEndValuesList.add(null); 63030da61d477bcb6cc7718f9516c444359352fe148George Mount } 63130da61d477bcb6cc7718f9516c444359352fe148George Mount 63230da61d477bcb6cc7718f9516c444359352fe148George Mount // Views that only exist in the end Scene 63330da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < unmatchedEnd.size(); i++) { 6344d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mEndValuesList.add(unmatchedEnd.valueAt(i)); 6354d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mStartValuesList.add(null); 63630da61d477bcb6cc7718f9516c444359352fe148George Mount } 63730da61d477bcb6cc7718f9516c444359352fe148George Mount } 63830da61d477bcb6cc7718f9516c444359352fe148George Mount 6397b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount private void matchStartAndEnd(TransitionValuesMaps startValues, 6404d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount TransitionValuesMaps endValues) { 6417b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount ArrayMap<View, TransitionValues> unmatchedStart = 6427b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount new ArrayMap<View, TransitionValues>(startValues.viewValues); 6437b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount ArrayMap<View, TransitionValues> unmatchedEnd = 6447b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount new ArrayMap<View, TransitionValues>(endValues.viewValues); 6457b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 6467b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount for (int i = 0; i < mMatchOrder.length; i++) { 6477b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount switch (mMatchOrder[i]) { 6487b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount case MATCH_INSTANCE: 6494d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount matchInstances(unmatchedStart, unmatchedEnd); 6507b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount break; 6510a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount case MATCH_NAME: 6524d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount matchNames(unmatchedStart, unmatchedEnd, 6537b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount startValues.nameValues, endValues.nameValues); 6547b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount break; 6557b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount case MATCH_ID: 6564d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount matchIds(unmatchedStart, unmatchedEnd, 6577b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount startValues.idValues, endValues.idValues); 6587b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount break; 6597b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount case MATCH_ITEM_ID: 6604d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount matchItemIds(unmatchedStart, unmatchedEnd, 6617b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount startValues.itemIdValues, endValues.itemIdValues); 6627b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount break; 6637b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 6647b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 6654d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount addUnmatched(unmatchedStart, unmatchedEnd); 6667b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount } 6677b75062fb05a9981faf3c0c9f840dbdb9e97e7f7George Mount 66830da61d477bcb6cc7718f9516c444359352fe148George Mount /** 669d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * This method, essentially a wrapper around all calls to createAnimator for all 670d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * possible target views, is called with the entire set of start/end 671faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * values. The implementation in Transition iterates through these lists 672d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * and calls {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)} 673faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * with each set of start/end values on this transition. The 674d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet subclass overrides this method and delegates it to 6752ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * each of its children in succession. 676faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 677faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 678faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 679d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues, 6804d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount TransitionValuesMaps endValues, ArrayList<TransitionValues> startValuesList, 6814d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount ArrayList<TransitionValues> endValuesList) { 682c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 683d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Log.d(LOG_TAG, "createAnimators() for " + this); 684c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 685199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 686d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount long minStartDelay = Long.MAX_VALUE; 687d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int minAnimator = mAnimators.size(); 688d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount SparseLongArray startDelays = new SparseLongArray(); 6894d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount int startValuesListCount = startValuesList.size(); 6904d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount for (int i = 0; i < startValuesListCount; ++i) { 691faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues start = startValuesList.get(i); 692faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase TransitionValues end = endValuesList.get(i); 6935030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount if (start != null && !start.targetedTransitions.contains(this)) { 6945030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount start = null; 6955030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount } 6965030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount if (end != null && !end.targetedTransitions.contains(this)) { 6975030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount end = null; 6985030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount } 6995030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount if (start == null && end == null) { 7005030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount continue; 7015030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount } 7025030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount // Only bother trying to animate with values that differ between start/end 7035030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount boolean isChanged = start == null || end == null || areValuesChanged(start, end); 7045030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount if (isChanged) { 705208dcade9373905b7168feb24db141cd71c45159George Mount if (DBG) { 706208dcade9373905b7168feb24db141cd71c45159George Mount View view = (end != null) ? end.view : start.view; 707208dcade9373905b7168feb24db141cd71c45159George Mount Log.d(LOG_TAG, " differing start/end values for view " + view); 708208dcade9373905b7168feb24db141cd71c45159George Mount if (start == null || end == null) { 709208dcade9373905b7168feb24db141cd71c45159George Mount Log.d(LOG_TAG, " " + ((start == null) ? 710208dcade9373905b7168feb24db141cd71c45159George Mount "start null, end non-null" : "start non-null, end null")); 711208dcade9373905b7168feb24db141cd71c45159George Mount } else { 712208dcade9373905b7168feb24db141cd71c45159George Mount for (String key : start.values.keySet()) { 713208dcade9373905b7168feb24db141cd71c45159George Mount Object startValue = start.values.get(key); 714208dcade9373905b7168feb24db141cd71c45159George Mount Object endValue = end.values.get(key); 715208dcade9373905b7168feb24db141cd71c45159George Mount if (startValue != endValue && !startValue.equals(endValue)) { 716208dcade9373905b7168feb24db141cd71c45159George Mount Log.d(LOG_TAG, " " + key + ": start(" + startValue + 717208dcade9373905b7168feb24db141cd71c45159George Mount "), end(" + endValue + ")"); 718c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 719c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 720c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 721208dcade9373905b7168feb24db141cd71c45159George Mount } 722208dcade9373905b7168feb24db141cd71c45159George Mount // TODO: what to do about targetIds and itemIds? 723208dcade9373905b7168feb24db141cd71c45159George Mount Animator animator = createAnimator(sceneRoot, start, end); 724208dcade9373905b7168feb24db141cd71c45159George Mount if (animator != null) { 725208dcade9373905b7168feb24db141cd71c45159George Mount // Save animation info for future cancellation purposes 726208dcade9373905b7168feb24db141cd71c45159George Mount View view = null; 727208dcade9373905b7168feb24db141cd71c45159George Mount TransitionValues infoValues = null; 728208dcade9373905b7168feb24db141cd71c45159George Mount if (end != null) { 729208dcade9373905b7168feb24db141cd71c45159George Mount view = end.view; 730208dcade9373905b7168feb24db141cd71c45159George Mount String[] properties = getTransitionProperties(); 731208dcade9373905b7168feb24db141cd71c45159George Mount if (view != null && properties != null && properties.length > 0) { 732208dcade9373905b7168feb24db141cd71c45159George Mount infoValues = new TransitionValues(); 733208dcade9373905b7168feb24db141cd71c45159George Mount infoValues.view = view; 734208dcade9373905b7168feb24db141cd71c45159George Mount TransitionValues newValues = endValues.viewValues.get(view); 735208dcade9373905b7168feb24db141cd71c45159George Mount if (newValues != null) { 736208dcade9373905b7168feb24db141cd71c45159George Mount for (int j = 0; j < properties.length; ++j) { 737208dcade9373905b7168feb24db141cd71c45159George Mount infoValues.values.put(properties[j], 738208dcade9373905b7168feb24db141cd71c45159George Mount newValues.values.get(properties[j])); 739199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 740208dcade9373905b7168feb24db141cd71c45159George Mount } 741208dcade9373905b7168feb24db141cd71c45159George Mount int numExistingAnims = runningAnimators.size(); 742208dcade9373905b7168feb24db141cd71c45159George Mount for (int j = 0; j < numExistingAnims; ++j) { 743208dcade9373905b7168feb24db141cd71c45159George Mount Animator anim = runningAnimators.keyAt(j); 744208dcade9373905b7168feb24db141cd71c45159George Mount AnimationInfo info = runningAnimators.get(anim); 745208dcade9373905b7168feb24db141cd71c45159George Mount if (info.values != null && info.view == view && 746208dcade9373905b7168feb24db141cd71c45159George Mount ((info.name == null && getName() == null) || 747208dcade9373905b7168feb24db141cd71c45159George Mount info.name.equals(getName()))) { 748208dcade9373905b7168feb24db141cd71c45159George Mount if (info.values.equals(infoValues)) { 749208dcade9373905b7168feb24db141cd71c45159George Mount // Favor the old animator 750208dcade9373905b7168feb24db141cd71c45159George Mount animator = null; 751208dcade9373905b7168feb24db141cd71c45159George Mount break; 752199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 753199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 754199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 755199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 756208dcade9373905b7168feb24db141cd71c45159George Mount } else { 757208dcade9373905b7168feb24db141cd71c45159George Mount view = (start != null) ? start.view : null; 758208dcade9373905b7168feb24db141cd71c45159George Mount } 759208dcade9373905b7168feb24db141cd71c45159George Mount if (animator != null) { 760208dcade9373905b7168feb24db141cd71c45159George Mount if (mPropagation != null) { 761208dcade9373905b7168feb24db141cd71c45159George Mount long delay = mPropagation 762208dcade9373905b7168feb24db141cd71c45159George Mount .getStartDelay(sceneRoot, this, start, end); 763208dcade9373905b7168feb24db141cd71c45159George Mount startDelays.put(mAnimators.size(), delay); 764208dcade9373905b7168feb24db141cd71c45159George Mount minStartDelay = Math.min(delay, minStartDelay); 765199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 7664c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount AnimationInfo info = new AnimationInfo(view, getName(), this, 767208dcade9373905b7168feb24db141cd71c45159George Mount sceneRoot.getWindowId(), infoValues); 768208dcade9373905b7168feb24db141cd71c45159George Mount runningAnimators.put(animator, info); 769208dcade9373905b7168feb24db141cd71c45159George Mount mAnimators.add(animator); 770c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 771c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 772faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 773faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 774d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (minStartDelay != 0) { 775d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount for (int i = 0; i < startDelays.size(); i++) { 776d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount int index = startDelays.keyAt(i); 777d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount Animator animator = mAnimators.get(index); 778d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount long delay = startDelays.valueAt(i) - minStartDelay + animator.getStartDelay(); 779d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount animator.setStartDelay(delay); 780d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 781d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 782faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 783faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 784faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 785faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Internal utility method for checking whether a given view/id 786faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is valid for this transition, where "valid" means that either 787faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition has no target/targetId list (the default, in which 788faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * cause the transition should act on all views in the hiearchy), or 789faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the given view is in the target list or the view id is in the 790faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * targetId list. If the target parameter is null, then the target list 791faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * is not checked (this is in the case of ListView items, where the 792faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * views are ignored and only the ids are used). 793faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 79430da61d477bcb6cc7718f9516c444359352fe148George Mount boolean isValidTarget(View target) { 79530da61d477bcb6cc7718f9516c444359352fe148George Mount int targetId = target.getId(); 796ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdExcludes != null && mTargetIdExcludes.contains(targetId)) { 797ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 798ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 799ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetExcludes != null && mTargetExcludes.contains(target)) { 800ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 801ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 802ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes != null && target != null) { 803ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeExcludes.size(); 804ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 805ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase Class type = mTargetTypeExcludes.get(i); 806ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (type.isInstance(target)) { 807ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return false; 808ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 809ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 810ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 8110a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount if (mTargetNameExcludes != null && target != null && target.getTransitionName() != null) { 8120a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount if (mTargetNameExcludes.contains(target.getTransitionName())) { 81330da61d477bcb6cc7718f9516c444359352fe148George Mount return false; 81430da61d477bcb6cc7718f9516c444359352fe148George Mount } 81530da61d477bcb6cc7718f9516c444359352fe148George Mount } 81630da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetIds.size() == 0 && mTargets.size() == 0 && 817cc82424b449f9d106d8d4caee74ad869d0e620ceGeorge Mount (mTargetTypes == null || mTargetTypes.isEmpty()) && 818cc82424b449f9d106d8d4caee74ad869d0e620ceGeorge Mount (mTargetNames == null || mTargetNames.isEmpty())) { 81930da61d477bcb6cc7718f9516c444359352fe148George Mount return true; 82030da61d477bcb6cc7718f9516c444359352fe148George Mount } 82130da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetIds.contains(targetId) || mTargets.contains(target)) { 822faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 823faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 8240a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount if (mTargetNames != null && mTargetNames.contains(target.getTransitionName())) { 825a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount return true; 826faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 827a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount if (mTargetTypes != null) { 828a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount for (int i = 0; i < mTargetTypes.size(); ++i) { 829a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount if (mTargetTypes.get(i).isInstance(target)) { 830faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return true; 831faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 832faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 833faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 834faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return false; 835faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 836faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 837e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount private static ArrayMap<Animator, AnimationInfo> getRunningAnimators() { 838199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = sRunningAnimators.get(); 839199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (runningAnimators == null) { 840199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators = new ArrayMap<Animator, AnimationInfo>(); 841199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase sRunningAnimators.set(runningAnimators); 842199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 843199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return runningAnimators; 844199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 845199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 846faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 8472ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * This is called internally once all animations have been set up by the 848d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * transition hierarchy. 849faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 850faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 851faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 852d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase protected void runAnimators() { 853199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 854d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Log.d(LOG_TAG, "runAnimators() on " + this); 855199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 856199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase start(); 857199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 858d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase // Now start every Animator that was previously created for this transition 859199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (Animator anim : mAnimators) { 860c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (DBG) { 861c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase Log.d(LOG_TAG, " anim: " + anim); 862c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 863199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (runningAnimators.containsKey(anim)) { 864199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase start(); 865199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runAnimator(anim, runningAnimators); 866199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 867faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 868199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mAnimators.clear(); 869199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 870faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 871faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 872199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase private void runAnimator(Animator animator, 873199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase final ArrayMap<Animator, AnimationInfo> runningAnimators) { 874e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase if (animator != null) { 875e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase // TODO: could be a single listener instance for all of them since it uses the param 876e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animator.addListener(new AnimatorListenerAdapter() { 877e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase @Override 878e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase public void onAnimationStart(Animator animation) { 879e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase mCurrentAnimators.add(animation); 880e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 881e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase @Override 882e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase public void onAnimationEnd(Animator animation) { 883199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.remove(animation); 884e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase mCurrentAnimators.remove(animation); 885e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 886e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase }); 887e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animate(animator); 888e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 889e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 890e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase 891faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 892d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Captures the values in the start scene for the properties that this 893d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition monitors. These values are then passed as the startValues 894d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * structure in a later call to 895d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 896d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The main concern for an implementation is what the 897d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * properties are that the transition cares about and what the values are 898d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * for all of those properties. The start and end values will be compared 899d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * later during the 900d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)} 901d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * method to determine what, if any, animations, should be run. 902d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 903d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Subclasses must implement this method. The method should only be called by the 904d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition system; it is not intended to be called from external classes.</p> 905d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 906d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param transitionValues The holder for any values that the Transition 907d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * wishes to store. Values are stored in the <code>values</code> field 908d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of this TransitionValues object and are keyed from 909d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * a String value. For example, to store a view's rotation value, 910d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * a transition might call 911d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionValues.values.put("appname:transitionname:rotation", 912d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * view.getRotation())</code>. The target view will already be stored in 913d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * the transitionValues structure when this method is called. 914d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 915d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #captureEndValues(TransitionValues) 916d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 917d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 918d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public abstract void captureStartValues(TransitionValues transitionValues); 919d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 920d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 921d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Captures the values in the end scene for the properties that this 922d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition monitors. These values are then passed as the endValues 923d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * structure in a later call to 924d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(ViewGroup, TransitionValues, TransitionValues)}. 925d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * The main concern for an implementation is what the 926faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * properties are that the transition cares about and what the values are 927faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * for all of those properties. The start and end values will be compared 9282ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * later during the 929d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)} 9302ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * method to determine what, if any, animations, should be run. 931faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 932d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Subclasses must implement this method. The method should only be called by the 933d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * transition system; it is not intended to be called from external classes.</p> 934d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 9352ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * @param transitionValues The holder for any values that the Transition 9362ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * wishes to store. Values are stored in the <code>values</code> field 9372ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * of this TransitionValues object and are keyed from 9382ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * a String value. For example, to store a view's rotation value, 9392ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * a transition might call 9402ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * <code>transitionValues.values.put("appname:transitionname:rotation", 9412ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * view.getRotation())</code>. The target view will already be stored in 9422ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * the transitionValues structure when this method is called. 943d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 944d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #captureStartValues(TransitionValues) 945d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @see #createAnimator(ViewGroup, TransitionValues, TransitionValues) 946faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 947d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public abstract void captureEndValues(TransitionValues transitionValues); 948faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 949faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 950d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Adds the id of a target view that this Transition is interested in 951faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animating. By default, there are no targetIds, and a Transition will 952faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listen for changes on every view in the hierarchy below the sceneRoot 953d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * of the Scene being transitioned into. Setting targetIds constrains 954faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition to only listen for, and act on, views with these IDs. 955faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Views with different IDs, or no IDs whatsoever, will be ignored. 956faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 957d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <p>Note that using ids to specify targets implies that ids should be unique 958b592d845147f051613fb62896b4e893015f8c413George Mount * within the view hierarchy underneath the scene root.</p> 959d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 960faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @see View#getId() 961d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param targetId The id of a target view, must be a positive number. 962d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition to which the targetId is added. 963d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Returning the same object makes it easier to chain calls during 964d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * construction, such as 965ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <code>transitionSet.addTransitions(new Fade()).addTarget(someId);</code> 966d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 967ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition addTarget(int targetId) { 968d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (targetId > 0) { 969d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargetIds.add(targetId); 970d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 971d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 972d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 973d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 974d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 9750a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * Adds the transitionName of a target view that this Transition is interested in 97630da61d477bcb6cc7718f9516c444359352fe148George Mount * animating. By default, there are no targetNames, and a Transition will 97730da61d477bcb6cc7718f9516c444359352fe148George Mount * listen for changes on every view in the hierarchy below the sceneRoot 97830da61d477bcb6cc7718f9516c444359352fe148George Mount * of the Scene being transitioned into. Setting targetNames constrains 9790a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * the Transition to only listen for, and act on, views with these transitionNames. 9800a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * Views with different transitionNames, or no transitionName whatsoever, will be ignored. 98130da61d477bcb6cc7718f9516c444359352fe148George Mount * 9820a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * <p>Note that transitionNames should be unique within the view hierarchy.</p> 98330da61d477bcb6cc7718f9516c444359352fe148George Mount * 9840a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * @see android.view.View#getTransitionName() 9850a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * @param targetName The transitionName of a target view, must be non-null. 9860a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * @return The Transition to which the target transitionName is added. 98730da61d477bcb6cc7718f9516c444359352fe148George Mount * Returning the same object makes it easier to chain calls during 98830da61d477bcb6cc7718f9516c444359352fe148George Mount * construction, such as 98930da61d477bcb6cc7718f9516c444359352fe148George Mount * <code>transitionSet.addTransitions(new Fade()).addTarget(someName);</code> 99030da61d477bcb6cc7718f9516c444359352fe148George Mount */ 99130da61d477bcb6cc7718f9516c444359352fe148George Mount public Transition addTarget(String targetName) { 99230da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetName != null) { 99358bbdbd1f1e2b2ed2e82caad6de6411fa2380cdcGeorge Mount if (mTargetNames == null) { 99430da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetNames = new ArrayList<String>(); 99530da61d477bcb6cc7718f9516c444359352fe148George Mount } 99630da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetNames.add(targetName); 99730da61d477bcb6cc7718f9516c444359352fe148George Mount } 99830da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 99930da61d477bcb6cc7718f9516c444359352fe148George Mount } 100030da61d477bcb6cc7718f9516c444359352fe148George Mount 100130da61d477bcb6cc7718f9516c444359352fe148George Mount /** 1002a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * Adds the Class of a target view that this Transition is interested in 1003a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * animating. By default, there are no targetTypes, and a Transition will 1004a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * listen for changes on every view in the hierarchy below the sceneRoot 1005a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * of the Scene being transitioned into. Setting targetTypes constrains 1006a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * the Transition to only listen for, and act on, views with these classes. 1007a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * Views with different classes will be ignored. 1008a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * 1009a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * <p>Note that any View that can be cast to targetType will be included, so 1010a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * if targetType is <code>View.class</code>, all Views will be included.</p> 1011a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * 1012a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @see #addTarget(int) 1013a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @see #addTarget(android.view.View) 1014a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @see #excludeTarget(Class, boolean) 1015a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @see #excludeChildren(Class, boolean) 1016a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * 1017a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @param targetType The type to include when running this transition. 1018a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * @return The Transition to which the target class was added. 1019a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * Returning the same object makes it easier to chain calls during 1020a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * construction, such as 1021a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount * <code>transitionSet.addTransitions(new Fade()).addTarget(ImageView.class);</code> 1022a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount */ 1023a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount public Transition addTarget(Class targetType) { 102430da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetType != null) { 102530da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetTypes == null) { 102630da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypes = new ArrayList<Class>(); 102730da61d477bcb6cc7718f9516c444359352fe148George Mount } 102830da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypes.add(targetType); 1029a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount } 1030a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount return this; 1031a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount } 1032a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount 1033a98fb7ab6a17d27395cf2c8e86060af49b861be6George Mount /** 1034d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Removes the given targetId from the list of ids that this Transition 1035d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * is interested in animating. 1036d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 1037d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param targetId The id of a target view, must be a positive number. 1038d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition from which the targetId is removed. 1039faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returning the same object makes it easier to chain calls during 1040faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * construction, such as 1041d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).removeTargetId(someId);</code> 1042faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1043ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition removeTarget(int targetId) { 1044d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (targetId > 0) { 1045d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargetIds.remove(targetId); 1046d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 1047faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 1048faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1049faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1050faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 10510a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * Removes the given targetName from the list of transitionNames that this Transition 105230da61d477bcb6cc7718f9516c444359352fe148George Mount * is interested in animating. 105330da61d477bcb6cc7718f9516c444359352fe148George Mount * 10540a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * @param targetName The transitionName of a target view, must not be null. 105530da61d477bcb6cc7718f9516c444359352fe148George Mount * @return The Transition from which the targetName is removed. 105630da61d477bcb6cc7718f9516c444359352fe148George Mount * Returning the same object makes it easier to chain calls during 105730da61d477bcb6cc7718f9516c444359352fe148George Mount * construction, such as 105830da61d477bcb6cc7718f9516c444359352fe148George Mount * <code>transitionSet.addTransitions(new Fade()).removeTargetName(someName);</code> 105930da61d477bcb6cc7718f9516c444359352fe148George Mount */ 106030da61d477bcb6cc7718f9516c444359352fe148George Mount public Transition removeTarget(String targetName) { 106130da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetName != null && mTargetNames != null) { 106230da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetNames.remove(targetName); 106330da61d477bcb6cc7718f9516c444359352fe148George Mount } 106430da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 106530da61d477bcb6cc7718f9516c444359352fe148George Mount } 106630da61d477bcb6cc7718f9516c444359352fe148George Mount 106730da61d477bcb6cc7718f9516c444359352fe148George Mount /** 1068ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given id to the list of target ids to exclude from this 1069ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 1070ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should be added to or removed from the excluded list. 1071ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1072ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1073ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1074ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1075ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1076ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1077ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1078ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1079ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 1080ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 1081ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 1082ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1083ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param targetId The id of a target to ignore when running this transition. 1084ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 1085ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 1086ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1087ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1088ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(int targetId, boolean exclude) { 108930da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetId >= 0) { 109030da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetIdExcludes = excludeObject(mTargetIdExcludes, targetId, exclude); 109130da61d477bcb6cc7718f9516c444359352fe148George Mount } 109230da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 109330da61d477bcb6cc7718f9516c444359352fe148George Mount } 109430da61d477bcb6cc7718f9516c444359352fe148George Mount 109530da61d477bcb6cc7718f9516c444359352fe148George Mount /** 10960a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * Whether to add the given transitionName to the list of target transitionNames to exclude 10970a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * from this transition. The <code>exclude</code> parameter specifies whether the target 109830da61d477bcb6cc7718f9516c444359352fe148George Mount * should be added to or removed from the excluded list. 109930da61d477bcb6cc7718f9516c444359352fe148George Mount * 110030da61d477bcb6cc7718f9516c444359352fe148George Mount * <p>Excluding targets is a general mechanism for allowing transitions to run on 110130da61d477bcb6cc7718f9516c444359352fe148George Mount * a view hierarchy while skipping target views that should not be part of 110230da61d477bcb6cc7718f9516c444359352fe148George Mount * the transition. For example, you may want to avoid animating children 110330da61d477bcb6cc7718f9516c444359352fe148George Mount * of a specific ListView or Spinner. Views can be excluded by their 11040a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * id, their instance reference, their transitionName, or by the Class of that view 110530da61d477bcb6cc7718f9516c444359352fe148George Mount * (eg, {@link Spinner}).</p> 110630da61d477bcb6cc7718f9516c444359352fe148George Mount * 110730da61d477bcb6cc7718f9516c444359352fe148George Mount * @see #excludeTarget(View, boolean) 110830da61d477bcb6cc7718f9516c444359352fe148George Mount * @see #excludeTarget(int, boolean) 110930da61d477bcb6cc7718f9516c444359352fe148George Mount * @see #excludeTarget(Class, boolean) 111030da61d477bcb6cc7718f9516c444359352fe148George Mount * 11110a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * @param targetName The name of a target to ignore when running this transition. 111230da61d477bcb6cc7718f9516c444359352fe148George Mount * @param exclude Whether to add the target to or remove the target from the 111330da61d477bcb6cc7718f9516c444359352fe148George Mount * current list of excluded targets. 111430da61d477bcb6cc7718f9516c444359352fe148George Mount * @return This transition object. 111530da61d477bcb6cc7718f9516c444359352fe148George Mount */ 11160a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount public Transition excludeTarget(String targetName, boolean exclude) { 11170a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount mTargetNameExcludes = excludeObject(mTargetNameExcludes, targetName, exclude); 1118ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1119ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1120ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1121ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1122ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the children of the given id to the list of targets to exclude 1123ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * from this transition. The <code>exclude</code> parameter specifies whether 1124ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the children of the target should be added to or removed from the excluded list. 1125ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Excluding children in this way provides a simple mechanism for excluding all 1126ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * children of specific targets, rather than individually excluding each 1127ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * child individually. 1128ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1129ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1130ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1131ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1132ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1133ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1134ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1135ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1136ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 1137ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 1138ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 1139ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1140ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param targetId The id of a target whose children should be ignored when running 1141ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * this transition. 1142ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 1143ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded-child targets. 1144ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1145ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1146ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(int targetId, boolean exclude) { 114730da61d477bcb6cc7718f9516c444359352fe148George Mount if (targetId >= 0) { 114830da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetIdChildExcludes = excludeObject(mTargetIdChildExcludes, targetId, exclude); 1149ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 115030da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 1151ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1152ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1153ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1154ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given target to the list of targets to exclude from this 1155ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 1156ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should be added to or removed from the excluded list. 1157ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1158ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1159ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1160ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1161ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1162ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1163ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1164ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1165ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 1166ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 1167ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 1168ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1169ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param target The target to ignore when running this transition. 1170ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 1171ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 1172ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1173ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1174ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(View target, boolean exclude) { 117530da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetExcludes = excludeObject(mTargetExcludes, target, exclude); 1176ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1177ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1178ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1179ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1180ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the children of given target to the list of target children 1181ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * to exclude from this transition. The <code>exclude</code> parameter specifies 1182ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * whether the target should be added to or removed from the excluded list. 1183ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1184ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1185ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1186ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1187ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1188ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1189ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1190ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1191ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 1192ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 1193ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 1194ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1195ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param target The target to ignore when running this transition. 1196ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target to or remove the target from the 1197ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded targets. 1198ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1199ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1200ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(View target, boolean exclude) { 120130da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetChildExcludes = excludeObject(mTargetChildExcludes, target, exclude); 1202ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1203ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1204ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1205ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1206ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility method to manage the boilerplate code that is the same whether we 1207ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * are excluding targets or their children. 1208ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 120930da61d477bcb6cc7718f9516c444359352fe148George Mount private static <T> ArrayList<T> excludeObject(ArrayList<T> list, T target, boolean exclude) { 1210ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (target != null) { 1211ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (exclude) { 1212ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.add(list, target); 1213ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } else { 1214ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = ArrayListManager.remove(list, target); 1215ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1216ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1217ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 1218ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1219ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1220ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1221ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given type to the list of types to exclude from this 1222ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * transition. The <code>exclude</code> parameter specifies whether the target 1223ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * type should be added to or removed from the excluded list. 1224ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1225ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1226ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1227ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1228ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1229ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1230ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1231ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1232ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(Class, boolean) 1233ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(int, boolean) 1234ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(View, boolean) 1235ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1236ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param type The type to ignore when running this transition. 1237ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target type to or remove it from the 1238ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded target types. 1239ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1240ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1241ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeTarget(Class type, boolean exclude) { 124230da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypeExcludes = excludeObject(mTargetTypeExcludes, type, exclude); 1243ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1244ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1245ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1246ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1247ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Whether to add the given type to the list of types whose children should 1248ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * be excluded from this transition. The <code>exclude</code> parameter 1249ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * specifies whether the target type should be added to or removed from 1250ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the excluded list. 1251ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1252ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>Excluding targets is a general mechanism for allowing transitions to run on 1253ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * a view hierarchy while skipping target views that should not be part of 1254ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * the transition. For example, you may want to avoid animating children 1255ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * of a specific ListView or Spinner. Views can be excluded either by their 1256ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * id, or by their instance reference, or by the Class of that view 1257ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * (eg, {@link Spinner}).</p> 1258ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1259ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeTarget(Class, boolean) 1260ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(int, boolean) 1261ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #excludeChildren(View, boolean) 1262ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 1263ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param type The type to ignore when running this transition. 1264ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @param exclude Whether to add the target type to or remove it from the 1265ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * current list of excluded target types. 1266ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @return This transition object. 1267ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 1268ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase public Transition excludeChildren(Class type, boolean exclude) { 126930da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypeChildExcludes = excludeObject(mTargetTypeChildExcludes, type, exclude); 1270ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return this; 1271ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1272ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 1273ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 1274faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Sets the target view instances that this Transition is interested in 1275faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * animating. By default, there are no targets, and a Transition will 1276faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listen for changes on every view in the hierarchy below the sceneRoot 1277faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * of the Scene being transitioned into. Setting targets constrains 1278faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * the Transition to only listen for, and act on, these views. 1279faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * All other views will be ignored. 1280faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1281ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * <p>The target list is like the {@link #addTarget(int) targetId} 1282faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * list except this list specifies the actual View instances, not the ids 1283faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * of the views. This is an important distinction when scene changes involve 1284faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * view hierarchies which have been inflated separately; different views may 1285faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * share the same id but not actually be the same instance. If the transition 1286ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * should treat those views as the same, then {@link #addTarget(int)} should be used 1287d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * instead of {@link #addTarget(View)}. If, on the other hand, scene changes involve 1288faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * changes all within the same view hierarchy, among views which do not 1289d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * necessarily have ids set on them, then the target list of views may be more 1290faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * convenient.</p> 1291faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1292ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * @see #addTarget(int) 1293d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param target A View on which the Transition will act, must be non-null. 1294d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return The Transition to which the target is added. 1295d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Returning the same object makes it easier to chain calls during 1296d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * construction, such as 1297d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).addTarget(someView);</code> 1298d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase */ 1299d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition addTarget(View target) { 1300d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargets.add(target); 1301d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1302d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 1303d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase 1304d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase /** 1305d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Removes the given target from the list of targets that this Transition 1306d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * is interested in animating. 1307d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 1308d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @param target The target view, must be non-null. 1309d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return Transition The Transition from which the target is removed. 1310faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Returning the same object makes it easier to chain calls during 1311faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * construction, such as 1312d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * <code>transitionSet.addTransitions(new Fade()).removeTarget(someView);</code> 1313faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1314d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition removeTarget(View target) { 1315d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (target != null) { 1316d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase mTargets.remove(target); 1317d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase } 1318faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return this; 1319faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1320faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1321faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 132230da61d477bcb6cc7718f9516c444359352fe148George Mount * Removes the given target from the list of targets that this Transition 132330da61d477bcb6cc7718f9516c444359352fe148George Mount * is interested in animating. 132430da61d477bcb6cc7718f9516c444359352fe148George Mount * 132530da61d477bcb6cc7718f9516c444359352fe148George Mount * @param target The type of the target view, must be non-null. 132630da61d477bcb6cc7718f9516c444359352fe148George Mount * @return Transition The Transition from which the target is removed. 132730da61d477bcb6cc7718f9516c444359352fe148George Mount * Returning the same object makes it easier to chain calls during 132830da61d477bcb6cc7718f9516c444359352fe148George Mount * construction, such as 132930da61d477bcb6cc7718f9516c444359352fe148George Mount * <code>transitionSet.addTransitions(new Fade()).removeTarget(someType);</code> 133030da61d477bcb6cc7718f9516c444359352fe148George Mount */ 133130da61d477bcb6cc7718f9516c444359352fe148George Mount public Transition removeTarget(Class target) { 133230da61d477bcb6cc7718f9516c444359352fe148George Mount if (target != null) { 133330da61d477bcb6cc7718f9516c444359352fe148George Mount mTargetTypes.remove(target); 133430da61d477bcb6cc7718f9516c444359352fe148George Mount } 133530da61d477bcb6cc7718f9516c444359352fe148George Mount return this; 133630da61d477bcb6cc7718f9516c444359352fe148George Mount } 133730da61d477bcb6cc7718f9516c444359352fe148George Mount 133830da61d477bcb6cc7718f9516c444359352fe148George Mount /** 133930da61d477bcb6cc7718f9516c444359352fe148George Mount * Returns the list of target IDs that this transition limits itself to 134030da61d477bcb6cc7718f9516c444359352fe148George Mount * tracking and animating. If the list is null or empty for 13410a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetNames()}, and 134230da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetTypes()} then this transition is 1343faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * not limited to specific views, and will handle changes to any views 1344faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * in the hierarchy of a scene change. 1345faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1346faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return the list of target IDs 1347faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1348d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public List<Integer> getTargetIds() { 1349faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mTargetIds; 1350faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1351faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1352faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 135330da61d477bcb6cc7718f9516c444359352fe148George Mount * Returns the list of target views that this transition limits itself to 135430da61d477bcb6cc7718f9516c444359352fe148George Mount * tracking and animating. If the list is null or empty for 13550a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetNames()}, and 135630da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetTypes()} then this transition is 1357faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * not limited to specific views, and will handle changes to any views 1358faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * in the hierarchy of a scene change. 1359faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1360faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @return the list of target views 1361faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1362d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public List<View> getTargets() { 1363faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return mTargets; 1364faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1365faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1366faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 13670a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * Returns the list of target transitionNames that this transition limits itself to 136830da61d477bcb6cc7718f9516c444359352fe148George Mount * tracking and animating. If the list is null or empty for 13690a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetNames()}, and 137030da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetTypes()} then this transition is 137130da61d477bcb6cc7718f9516c444359352fe148George Mount * not limited to specific views, and will handle changes to any views 137230da61d477bcb6cc7718f9516c444359352fe148George Mount * in the hierarchy of a scene change. 137330da61d477bcb6cc7718f9516c444359352fe148George Mount * 13740a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * @return the list of target transitionNames 13750a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount */ 13760a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount public List<String> getTargetNames() { 13770a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount return mTargetNames; 13780a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount } 13790a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount 13800a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount /** 13810a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * To be removed before L release. 13820a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * @hide 138330da61d477bcb6cc7718f9516c444359352fe148George Mount */ 138430da61d477bcb6cc7718f9516c444359352fe148George Mount public List<String> getTargetViewNames() { 138530da61d477bcb6cc7718f9516c444359352fe148George Mount return mTargetNames; 138630da61d477bcb6cc7718f9516c444359352fe148George Mount } 138730da61d477bcb6cc7718f9516c444359352fe148George Mount 138830da61d477bcb6cc7718f9516c444359352fe148George Mount /** 13890a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * Returns the list of target transitionNames that this transition limits itself to 139030da61d477bcb6cc7718f9516c444359352fe148George Mount * tracking and animating. If the list is null or empty for 13910a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount * {@link #getTargetIds()}, {@link #getTargets()}, {@link #getTargetNames()}, and 139230da61d477bcb6cc7718f9516c444359352fe148George Mount * {@link #getTargetTypes()} then this transition is 139330da61d477bcb6cc7718f9516c444359352fe148George Mount * not limited to specific views, and will handle changes to any views 139430da61d477bcb6cc7718f9516c444359352fe148George Mount * in the hierarchy of a scene change. 139530da61d477bcb6cc7718f9516c444359352fe148George Mount * 139630da61d477bcb6cc7718f9516c444359352fe148George Mount * @return the list of target Types 139730da61d477bcb6cc7718f9516c444359352fe148George Mount */ 139830da61d477bcb6cc7718f9516c444359352fe148George Mount public List<Class> getTargetTypes() { 139930da61d477bcb6cc7718f9516c444359352fe148George Mount return mTargetTypes; 140030da61d477bcb6cc7718f9516c444359352fe148George Mount } 140130da61d477bcb6cc7718f9516c444359352fe148George Mount 140230da61d477bcb6cc7718f9516c444359352fe148George Mount /** 1403faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Recursive method that captures values for the given view and the 1404faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * hierarchy underneath it. 1405faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param sceneRoot The root of the view hierarchy being captured 1406faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param start true if this capture is happening before the scene change, 1407faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * false otherwise 1408faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1409faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void captureValues(ViewGroup sceneRoot, boolean start) { 1410df32aa87150768795816852c6393306893467ecaChet Haase clearValues(start); 141130da61d477bcb6cc7718f9516c444359352fe148George Mount if ((mTargetIds.size() > 0 || mTargets.size() > 0) 141230da61d477bcb6cc7718f9516c444359352fe148George Mount && (mTargetNames == null || mTargetNames.isEmpty()) 141330da61d477bcb6cc7718f9516c444359352fe148George Mount && (mTargetTypes == null || mTargetTypes.isEmpty())) { 141430da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < mTargetIds.size(); ++i) { 141530da61d477bcb6cc7718f9516c444359352fe148George Mount int id = mTargetIds.get(i); 141630da61d477bcb6cc7718f9516c444359352fe148George Mount View view = sceneRoot.findViewById(id); 141730da61d477bcb6cc7718f9516c444359352fe148George Mount if (view != null) { 141830da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues values = new TransitionValues(); 141930da61d477bcb6cc7718f9516c444359352fe148George Mount values.view = view; 142030da61d477bcb6cc7718f9516c444359352fe148George Mount if (start) { 142130da61d477bcb6cc7718f9516c444359352fe148George Mount captureStartValues(values); 142230da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 142330da61d477bcb6cc7718f9516c444359352fe148George Mount captureEndValues(values); 142430da61d477bcb6cc7718f9516c444359352fe148George Mount } 14255030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount values.targetedTransitions.add(this); 142630da61d477bcb6cc7718f9516c444359352fe148George Mount capturePropagationValues(values); 142730da61d477bcb6cc7718f9516c444359352fe148George Mount if (start) { 14285030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount addViewValues(mStartValues, view, values); 142930da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 14305030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount addViewValues(mEndValues, view, values); 1431faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1432faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1433faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 143430da61d477bcb6cc7718f9516c444359352fe148George Mount for (int i = 0; i < mTargets.size(); ++i) { 143530da61d477bcb6cc7718f9516c444359352fe148George Mount View view = mTargets.get(i); 143630da61d477bcb6cc7718f9516c444359352fe148George Mount TransitionValues values = new TransitionValues(); 143730da61d477bcb6cc7718f9516c444359352fe148George Mount values.view = view; 143830da61d477bcb6cc7718f9516c444359352fe148George Mount if (start) { 143930da61d477bcb6cc7718f9516c444359352fe148George Mount captureStartValues(values); 144030da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 144130da61d477bcb6cc7718f9516c444359352fe148George Mount captureEndValues(values); 144230da61d477bcb6cc7718f9516c444359352fe148George Mount } 14435030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount values.targetedTransitions.add(this); 144430da61d477bcb6cc7718f9516c444359352fe148George Mount capturePropagationValues(values); 144530da61d477bcb6cc7718f9516c444359352fe148George Mount if (start) { 14462deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount addViewValues(mStartValues, view, values); 144730da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 14482deeaa33143362846299bb424b3b1a52ca45deebGeorge Mount addViewValues(mEndValues, view, values); 1449faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1450faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1451faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1452faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase captureHierarchy(sceneRoot, start); 1453faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1454d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount if (!start && mNameOverrides != null) { 1455d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount int numOverrides = mNameOverrides.size(); 1456d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount ArrayList<View> overriddenViews = new ArrayList<View>(numOverrides); 1457d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount for (int i = 0; i < numOverrides; i++) { 1458d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount String fromName = mNameOverrides.keyAt(i); 1459d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount overriddenViews.add(mStartValues.nameValues.remove(fromName)); 1460d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1461d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount for (int i = 0; i < numOverrides; i++) { 1462d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount View view = overriddenViews.get(i); 1463d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount if (view != null) { 1464d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount String toName = mNameOverrides.valueAt(i); 1465d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount mStartValues.nameValues.put(toName, view); 1466d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1467d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1468d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 1469faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1470faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 147130da61d477bcb6cc7718f9516c444359352fe148George Mount static void addViewValues(TransitionValuesMaps transitionValuesMaps, 14725030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount View view, TransitionValues transitionValues) { 147330da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.viewValues.put(view, transitionValues); 147430da61d477bcb6cc7718f9516c444359352fe148George Mount int id = view.getId(); 147530da61d477bcb6cc7718f9516c444359352fe148George Mount if (id >= 0) { 147630da61d477bcb6cc7718f9516c444359352fe148George Mount if (transitionValuesMaps.idValues.indexOfKey(id) >= 0) { 147730da61d477bcb6cc7718f9516c444359352fe148George Mount // Duplicate IDs cannot match by ID. 147830da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.idValues.put(id, null); 147930da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 148030da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.idValues.put(id, view); 148130da61d477bcb6cc7718f9516c444359352fe148George Mount } 148230da61d477bcb6cc7718f9516c444359352fe148George Mount } 14830a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount String name = view.getTransitionName(); 148430da61d477bcb6cc7718f9516c444359352fe148George Mount if (name != null) { 148530da61d477bcb6cc7718f9516c444359352fe148George Mount if (transitionValuesMaps.nameValues.containsKey(name)) { 14860a2ae002e60f7ea9b6bea282086b5eb0ae3c6e51George Mount // Duplicate transitionNames: cannot match by transitionName. 148730da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.nameValues.put(name, null); 148830da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 148930da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.nameValues.put(name, view); 149030da61d477bcb6cc7718f9516c444359352fe148George Mount } 149130da61d477bcb6cc7718f9516c444359352fe148George Mount } 149230da61d477bcb6cc7718f9516c444359352fe148George Mount if (view.getParent() instanceof ListView) { 149330da61d477bcb6cc7718f9516c444359352fe148George Mount ListView listview = (ListView) view.getParent(); 149430da61d477bcb6cc7718f9516c444359352fe148George Mount if (listview.getAdapter().hasStableIds()) { 149530da61d477bcb6cc7718f9516c444359352fe148George Mount int position = listview.getPositionForView(view); 149630da61d477bcb6cc7718f9516c444359352fe148George Mount long itemId = listview.getItemIdAtPosition(position); 149730da61d477bcb6cc7718f9516c444359352fe148George Mount if (transitionValuesMaps.itemIdValues.indexOfKey(itemId) >= 0) { 149830da61d477bcb6cc7718f9516c444359352fe148George Mount // Duplicate item IDs: cannot match by item ID. 149930da61d477bcb6cc7718f9516c444359352fe148George Mount View alreadyMatched = transitionValuesMaps.itemIdValues.get(itemId); 150030da61d477bcb6cc7718f9516c444359352fe148George Mount if (alreadyMatched != null) { 15015030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount alreadyMatched.setHasTransientState(false); 150230da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.itemIdValues.put(itemId, null); 150330da61d477bcb6cc7718f9516c444359352fe148George Mount } 150430da61d477bcb6cc7718f9516c444359352fe148George Mount } else { 15055030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount view.setHasTransientState(true); 150630da61d477bcb6cc7718f9516c444359352fe148George Mount transitionValuesMaps.itemIdValues.put(itemId, view); 150730da61d477bcb6cc7718f9516c444359352fe148George Mount } 150830da61d477bcb6cc7718f9516c444359352fe148George Mount } 150930da61d477bcb6cc7718f9516c444359352fe148George Mount } 151030da61d477bcb6cc7718f9516c444359352fe148George Mount } 151130da61d477bcb6cc7718f9516c444359352fe148George Mount 1512faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1513df32aa87150768795816852c6393306893467ecaChet Haase * Clear valuesMaps for specified start/end state 1514df32aa87150768795816852c6393306893467ecaChet Haase * 1515df32aa87150768795816852c6393306893467ecaChet Haase * @param start true if the start values should be cleared, false otherwise 1516df32aa87150768795816852c6393306893467ecaChet Haase */ 1517df32aa87150768795816852c6393306893467ecaChet Haase void clearValues(boolean start) { 1518df32aa87150768795816852c6393306893467ecaChet Haase if (start) { 1519df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.viewValues.clear(); 1520df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.idValues.clear(); 1521df32aa87150768795816852c6393306893467ecaChet Haase mStartValues.itemIdValues.clear(); 1522d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount mStartValues.nameValues.clear(); 15234d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mStartValuesList = null; 1524df32aa87150768795816852c6393306893467ecaChet Haase } else { 1525df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.viewValues.clear(); 1526df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.idValues.clear(); 1527df32aa87150768795816852c6393306893467ecaChet Haase mEndValues.itemIdValues.clear(); 1528d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount mEndValues.nameValues.clear(); 15294d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mEndValuesList = null; 1530df32aa87150768795816852c6393306893467ecaChet Haase } 1531df32aa87150768795816852c6393306893467ecaChet Haase } 1532df32aa87150768795816852c6393306893467ecaChet Haase 1533df32aa87150768795816852c6393306893467ecaChet Haase /** 1534faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Recursive method which captures values for an entire view hierarchy, 1535faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * starting at some root view. Transitions without targetIDs will use this 1536faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * method to capture values for all possible views. 1537faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1538faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param view The view for which to capture values. Children of this View 1539faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will also be captured, recursively down to the leaf nodes. 1540faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param start true if values are being captured in the start scene, false 1541faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * otherwise. 1542faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1543faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase private void captureHierarchy(View view, boolean start) { 1544faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view == null) { 1545faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return; 1546faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 154730da61d477bcb6cc7718f9516c444359352fe148George Mount int id = view.getId(); 1548ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdExcludes != null && mTargetIdExcludes.contains(id)) { 1549ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1550ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1551ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetExcludes != null && mTargetExcludes.contains(view)) { 1552ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1553ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1554ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes != null && view != null) { 1555ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeExcludes.size(); 1556ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 1557ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeExcludes.get(i).isInstance(view)) { 1558ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1559ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1560ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1561ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1562e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (view.getParent() instanceof ViewGroup) { 1563e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount TransitionValues values = new TransitionValues(); 1564e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount values.view = view; 1565e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (start) { 1566e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount captureStartValues(values); 1567faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1568e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount captureEndValues(values); 1569faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 15705030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount values.targetedTransitions.add(this); 1571d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount capturePropagationValues(values); 1572e180337ee99b9155fe441ea55451f4d2167b5d9aGeorge Mount if (start) { 15735030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount addViewValues(mStartValues, view, values); 1574faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 15755030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount addViewValues(mEndValues, view, values); 1576faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1577faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1578faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (view instanceof ViewGroup) { 1579ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase // Don't traverse child hierarchy if there are any child-excludes on this view 1580ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetIdChildExcludes != null && mTargetIdChildExcludes.contains(id)) { 1581ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1582ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1583ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetChildExcludes != null && mTargetChildExcludes.contains(view)) { 1584ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1585ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 158630da61d477bcb6cc7718f9516c444359352fe148George Mount if (mTargetTypeChildExcludes != null) { 1587ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase int numTypes = mTargetTypeChildExcludes.size(); 1588ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase for (int i = 0; i < numTypes; ++i) { 1589ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (mTargetTypeChildExcludes.get(i).isInstance(view)) { 1590ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return; 1591ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1592ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1593ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 1594faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ViewGroup parent = (ViewGroup) view; 1595faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < parent.getChildCount(); ++i) { 1596faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase captureHierarchy(parent.getChildAt(i), start); 1597faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1598faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1599faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1600faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1601faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 16026ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * This method can be called by transitions to get the TransitionValues for 16036ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * any particular view during the transition-playing process. This might be 16046ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * necessary, for example, to query the before/after state of related views 16056ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase * for a given transition. 16066ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase */ 1607d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public TransitionValues getTransitionValues(View view, boolean start) { 16086ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase if (mParent != null) { 16096ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return mParent.getTransitionValues(view, start); 16106ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 16116ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase TransitionValuesMaps valuesMaps = start ? mStartValues : mEndValues; 161230da61d477bcb6cc7718f9516c444359352fe148George Mount return valuesMaps.viewValues.get(view); 16136ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 16146ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 16156ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase /** 16164d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * Find the matched start or end value for a given View. This is only valid 16174d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * after playTransition starts. For example, it will be valid in 16184d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues)}, but not 16194d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * in {@link #captureStartValues(TransitionValues)}. 16204d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * 16214d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * @param view The view to find the match for. 16224d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * @param viewInStart Is View from the start values or end values. 16234d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * @return The matching TransitionValues for view in either start or end values, depending 16244d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount * on viewInStart or null if there is no match for the given view. 16254d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount */ 16264d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount TransitionValues getMatchedTransitionValues(View view, boolean viewInStart) { 16274d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount if (mParent != null) { 16284d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount return mParent.getMatchedTransitionValues(view, viewInStart); 16294d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount } 16304d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount ArrayList<TransitionValues> lookIn = viewInStart ? mStartValuesList : mEndValuesList; 16314d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount if (lookIn == null) { 16324d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount return null; 16334d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount } 16344d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount int count = lookIn.size(); 16354d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount int index = -1; 16364d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount for (int i = 0; i < count; i++) { 16374d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount TransitionValues values = lookIn.get(i); 16384d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount if (values == null) { 16394d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount return null; 16404d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount } 16414d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount if (values.view == view) { 16424d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount index = i; 16434d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount break; 16444d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount } 16454d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount } 16464d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount TransitionValues values = null; 16474d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount if (index >= 0) { 16484d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount ArrayList<TransitionValues> matchIn = viewInStart ? mEndValuesList : mStartValuesList; 16494d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount values = matchIn.get(index); 16504d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount } 16514d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount return values; 16524d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount } 16534d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount 16544d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount /** 1655199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Pauses this transition, sending out calls to {@link 1656199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * TransitionListener#onTransitionPause(Transition)} to all listeners 1657199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * and pausing all running animators started by this transition. 1658199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1659199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @hide 1660199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1661cf68aad3164303df59b2a669d186a94533c9c743George Mount public void pause(View sceneRoot) { 1662a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (!mEnded) { 1663a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1664a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numOldAnims = runningAnimators.size(); 166551c014843a6d339d115dfa88b9ee2fff90a8b844George Mount if (sceneRoot != null) { 166651c014843a6d339d115dfa88b9ee2fff90a8b844George Mount WindowId windowId = sceneRoot.getWindowId(); 166751c014843a6d339d115dfa88b9ee2fff90a8b844George Mount for (int i = numOldAnims - 1; i >= 0; i--) { 166851c014843a6d339d115dfa88b9ee2fff90a8b844George Mount AnimationInfo info = runningAnimators.valueAt(i); 16696276cd4b8defba1b6fef47ebc1bbe14498655b94George Mount if (info.view != null && windowId != null && windowId.equals(info.windowId)) { 167051c014843a6d339d115dfa88b9ee2fff90a8b844George Mount Animator anim = runningAnimators.keyAt(i); 167151c014843a6d339d115dfa88b9ee2fff90a8b844George Mount anim.pause(); 167251c014843a6d339d115dfa88b9ee2fff90a8b844George Mount } 1673cf68aad3164303df59b2a669d186a94533c9c743George Mount } 1674a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1675a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (mListeners != null && mListeners.size() > 0) { 1676a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayList<TransitionListener> tmpListeners = 1677a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1678a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numListeners = tmpListeners.size(); 1679a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = 0; i < numListeners; ++i) { 1680a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase tmpListeners.get(i).onTransitionPause(this); 1681a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1682199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1683a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mPaused = true; 1684199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1685199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1686199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1687199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1688199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Resumes this transition, sending out calls to {@link 1689199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * TransitionListener#onTransitionPause(Transition)} to all listeners 1690199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * and pausing all running animators started by this transition. 1691199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 1692199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @hide 1693199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 1694cf68aad3164303df59b2a669d186a94533c9c743George Mount public void resume(View sceneRoot) { 1695199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (mPaused) { 1696a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (!mEnded) { 1697a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1698a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numOldAnims = runningAnimators.size(); 1699cf68aad3164303df59b2a669d186a94533c9c743George Mount WindowId windowId = sceneRoot.getWindowId(); 1700a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1701cf68aad3164303df59b2a669d186a94533c9c743George Mount AnimationInfo info = runningAnimators.valueAt(i); 17026276cd4b8defba1b6fef47ebc1bbe14498655b94George Mount if (info.view != null && windowId != null && windowId.equals(info.windowId)) { 1703cf68aad3164303df59b2a669d186a94533c9c743George Mount Animator anim = runningAnimators.keyAt(i); 1704cf68aad3164303df59b2a669d186a94533c9c743George Mount anim.resume(); 1705cf68aad3164303df59b2a669d186a94533c9c743George Mount } 1706a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1707a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase if (mListeners != null && mListeners.size() > 0) { 1708a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase ArrayList<TransitionListener> tmpListeners = 1709a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1710a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase int numListeners = tmpListeners.size(); 1711a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase for (int i = 0; i < numListeners; ++i) { 1712a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase tmpListeners.get(i).onTransitionResume(this); 1713a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase } 1714199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1715199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1716199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase mPaused = false; 1717199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1718199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1719199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 1720199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 1721faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Called by TransitionManager to play the transition. This calls 1722d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimators() to set things up and create all of the animations and then 17232ea7f8b9c5f903050d42c1af57406bf528979f45Chet Haase * runAnimations() to actually start the animations. 1724faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 17256ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase void playTransition(ViewGroup sceneRoot) { 17264d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mStartValuesList = new ArrayList<TransitionValues>(); 17274d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount mEndValuesList = new ArrayList<TransitionValues>(); 17284d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount matchStartAndEnd(mStartValues, mEndValues); 17294d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount 1730199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators(); 1731199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase int numOldAnims = runningAnimators.size(); 1732fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount WindowId windowId = sceneRoot.getWindowId(); 1733199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase for (int i = numOldAnims - 1; i >= 0; i--) { 1734199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Animator anim = runningAnimators.keyAt(i); 1735199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (anim != null) { 1736199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase AnimationInfo oldInfo = runningAnimators.get(anim); 1737fe361d2113b8f3c54797d7bd720ca739328bd7aaGeorge Mount if (oldInfo != null && oldInfo.view != null && oldInfo.windowId == windowId) { 1738199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues oldValues = oldInfo.values; 1739199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase View oldView = oldInfo.view; 17405030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount TransitionValues startValues = getTransitionValues(oldView, true); 17415030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount TransitionValues endValues = getMatchedTransitionValues(oldView, true); 17425030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount boolean cancel = (startValues != null || endValues != null) && 17435030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount oldInfo.transition.areValuesChanged(oldValues, endValues); 1744199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (cancel) { 1745199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (anim.isRunning() || anim.isStarted()) { 1746199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 1747199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Log.d(LOG_TAG, "Canceling anim " + anim); 1748199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1749199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase anim.cancel(); 1750199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } else { 1751199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase if (DBG) { 1752199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase Log.d(LOG_TAG, "removing anim from info list: " + anim); 1753199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1754199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase runningAnimators.remove(anim); 1755199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1756199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1757199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1758199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1759199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 1760199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 17614d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount createAnimators(sceneRoot, mStartValues, mEndValues, mStartValuesList, mEndValuesList); 1762d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase runAnimators(); 1763faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1764faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 17654c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount boolean areValuesChanged(TransitionValues oldValues, TransitionValues newValues) { 17664c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount boolean valuesChanged = false; 17674c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount // if oldValues null, then transition didn't care to stash values, 17684c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount // and won't get canceled 17694c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount if (oldValues != null && newValues != null) { 1770c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu String[] properties = getTransitionProperties(); 1771c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu if (properties != null) { 1772c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu int count = properties.length; 1773c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu for (int i = 0; i < count; i++) { 1774c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu if (isValueChanged(oldValues, newValues, properties[i])) { 1775c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu valuesChanged = true; 1776c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu break; 1777c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu } 1778c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu } 1779c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu } else { 1780c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu for (String key : oldValues.values.keySet()) { 1781c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu if (isValueChanged(oldValues, newValues, key)) { 1782c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu valuesChanged = true; 1783c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu break; 17844c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount } 17854c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount } 17864c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount } 17874c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount } 17884c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount return valuesChanged; 17894c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount } 17904c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount 1791c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu private static boolean isValueChanged(TransitionValues oldValues, TransitionValues newValues, 1792c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu String key) { 1793cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount if (oldValues.values.containsKey(key) != newValues.values.containsKey(key)) { 1794cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount // The transition didn't care about this particular value, so we don't care, either. 1795cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount return false; 1796cba01b2310e78fc2114ceed285f4e134469ae62bGeorge Mount } 1797c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu Object oldValue = oldValues.values.get(key); 1798c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu Object newValue = newValues.values.get(key); 17995030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount boolean changed; 18005030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount if (oldValue == null && newValue == null) { 18015030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount // both are null 18025030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount changed = false; 18035030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount } else if (oldValue == null || newValue == null) { 18045030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount // one is null 18055030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount changed = true; 18065030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount } else { 18075030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount // neither is null 18085030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount changed = !oldValue.equals(newValue); 18095030c7f6f15c5c2cac2403f863e4f618a8cfaedfGeorge Mount } 1810c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu if (DBG && changed) { 1811c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu Log.d(LOG_TAG, "Transition.playTransition: " + 1812c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu "oldValue != newValue for " + key + 1813c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu ": old, new = " + oldValue + ", " + newValue); 1814c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu } 1815c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu return changed; 1816c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu } 1817c94e2b393f6eba684ee2c84eaa50746fc1459d0fDake Gu 1818faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1819faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This is a utility method used by subclasses to handle standard parts of 1820faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * setting up and running an Animator: it sets the {@link #getDuration() 1821faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * duration} and the {@link #getStartDelay() startDelay}, starts the 1822199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation, and, when the animator ends, calls {@link #end()}. 1823faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1824faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param animator The Animator to be run during this transition. 1825faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1826faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1827faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1828faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase protected void animate(Animator animator) { 1829faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase // TODO: maybe pass auto-end as a boolean parameter? 1830faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (animator == null) { 1831199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 1832faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } else { 1833faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getDuration() >= 0) { 1834faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.setDuration(getDuration()); 1835faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1836faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getStartDelay() >= 0) { 1837d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount animator.setStartDelay(getStartDelay() + animator.getStartDelay()); 1838faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1839faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (getInterpolator() != null) { 1840faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.setInterpolator(getInterpolator()); 1841faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1842faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.addListener(new AnimatorListenerAdapter() { 1843faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 1844faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onAnimationEnd(Animator animation) { 1845199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase end(); 1846faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animation.removeListener(this); 1847faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1848faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase }); 1849faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase animator.start(); 1850faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1851faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1852faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1853faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1854faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method is called automatically by the transition and 1855d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet classes prior to a Transition subclass starting; 1856faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * subclasses should not need to call it directly. 1857faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1858faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1859faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1860199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void start() { 1861faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mNumInstances == 0) { 1862faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1863faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1864faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1865faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1866faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1867faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionStart(this); 1868faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1869faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1870a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mEnded = false; 1871faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1872faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mNumInstances++; 1873faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1874faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1875faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1876faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method is called automatically by the Transition and 1877d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSet classes when a transition finishes, either because 1878faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * a transition did nothing (returned a null Animator from 1879d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link Transition#createAnimator(ViewGroup, TransitionValues, 1880faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * TransitionValues)}) or because the transition returned a valid 1881199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Animator and end() was called in the onAnimationEnd() 1882faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * callback of the AnimatorListener. 1883faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1884faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 1885faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1886199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void end() { 1887faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase --mNumInstances; 1888faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mNumInstances == 0) { 1889faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1890faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1891faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1892faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1893faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1894faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionEnd(this); 1895faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1896faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 18976ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < mStartValues.itemIdValues.size(); ++i) { 189830da61d477bcb6cc7718f9516c444359352fe148George Mount View view = mStartValues.itemIdValues.valueAt(i); 189930da61d477bcb6cc7718f9516c444359352fe148George Mount if (view != null) { 190030da61d477bcb6cc7718f9516c444359352fe148George Mount view.setHasTransientState(false); 1901faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1902faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 19036ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase for (int i = 0; i < mEndValues.itemIdValues.size(); ++i) { 190430da61d477bcb6cc7718f9516c444359352fe148George Mount View view = mEndValues.itemIdValues.valueAt(i); 190530da61d477bcb6cc7718f9516c444359352fe148George Mount if (view != null) { 190630da61d477bcb6cc7718f9516c444359352fe148George Mount view.setHasTransientState(false); 1907faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1908faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1909a56205c485deb5a95c1e4f79ef2b09d14cbc9524Chet Haase mEnded = true; 1910faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1911faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1912faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1913faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1914faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * This method cancels a transition that is currently running. 1915d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * 1916d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @hide 1917faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1918199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase protected void cancel() { 1919e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase int numAnimators = mCurrentAnimators.size(); 192025a738fb257aacfc87d3363a834ed6e0b050c3b1Chet Haase for (int i = numAnimators - 1; i >= 0; i--) { 1921e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase Animator animator = mCurrentAnimators.get(i); 1922e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase animator.cancel(); 1923e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase } 1924faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners != null && mListeners.size() > 0) { 1925faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase ArrayList<TransitionListener> tmpListeners = 1926faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase (ArrayList<TransitionListener>) mListeners.clone(); 1927faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase int numListeners = tmpListeners.size(); 1928faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase for (int i = 0; i < numListeners; ++i) { 1929faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase tmpListeners.get(i).onTransitionCancel(this); 1930faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1931faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1932faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1933faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1934faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1935faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Adds a listener to the set of listeners that are sent events through the 1936faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * life of an animation, such as start, repeat, and end. 1937faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1938faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param listener the listener to be added to the current set of listeners 1939faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * for this animation. 1940d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 1941faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1942d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition addListener(TransitionListener listener) { 1943faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners == null) { 1944faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners = new ArrayList<TransitionListener>(); 1945faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1946faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners.add(listener); 1947d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1948faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1949faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1950faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 1951faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Removes a listener from the set listening to this animation. 1952faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 1953faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param listener the listener to be removed from the current set of 1954faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * listeners for this transition. 1955d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * @return This transition object. 1956faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 1957d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase public Transition removeListener(TransitionListener listener) { 1958faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners == null) { 1959d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1960faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1961faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners.remove(listener); 1962faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase if (mListeners.size() == 0) { 1963faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase mListeners = null; 1964faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1965d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 1966faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 1967faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 1968d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1969d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Sets the callback to use to find the epicenter of a Transition. A null value indicates 1970dc21d3b2804c24fe29ec860796d11185901364c4George Mount * that there is no epicenter in the Transition and onGetEpicenter() will return null. 1971d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Transitions like {@link android.transition.Explode} use a point or Rect to orient 1972d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the direction of travel. This is called the epicenter of the Transition and is 1973d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * typically centered on a touched View. The 1974d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} allows a Transition to 1975d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * dynamically retrieve the epicenter during a Transition. 1976d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param epicenterCallback The callback to use to find the epicenter of the Transition. 1977d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1978d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void setEpicenterCallback(EpicenterCallback epicenterCallback) { 1979d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mEpicenterCallback = epicenterCallback; 1980d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1981d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1982d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1983d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Returns the callback used to find the epicenter of the Transition. 1984d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Transitions like {@link android.transition.Explode} use a point or Rect to orient 1985d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the direction of travel. This is called the epicenter of the Transition and is 1986d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * typically centered on a touched View. The 1987d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} allows a Transition to 1988d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * dynamically retrieve the epicenter during a Transition. 1989d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return the callback used to find the epicenter of the Transition. 1990d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 1991d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public EpicenterCallback getEpicenterCallback() { 1992d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return mEpicenterCallback; 1993d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 1994d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 1995d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 1996d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Returns the epicenter as specified by the 1997d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists. 1998d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return the epicenter as specified by the 1999d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Transition.EpicenterCallback} or null if no callback exists. 2000d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback) 2001d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 2002d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public Rect getEpicenter() { 2003d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (mEpicenterCallback == null) { 2004d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return null; 2005d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2006dc21d3b2804c24fe29ec860796d11185901364c4George Mount return mEpicenterCallback.onGetEpicenter(this); 2007d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2008d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 2009d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 2010ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * Sets the algorithm used to calculate two-dimensional interpolation. 2011ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * <p> 2012ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * Transitions such as {@link android.transition.ChangeBounds} move Views, typically 2013ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * in a straight path between the start and end positions. Applications that desire to 2014ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * have these motions move in a curve can change how Views interpolate in two dimensions 2015ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * by extending PathMotion and implementing 2016ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * {@link android.transition.PathMotion#getPath(float, float, float, float)}. 2017ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * </p> 2018f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <p> 2019f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * When describing in XML, use a nested XML tag for the path motion. It can be one of 2020f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * the built-in tags <code>arcMotion</code> or <code>patternPathMotion</code> or it can 2021f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * be a custom PathMotion using <code>pathMotion</code> with the <code>class</code> 2022f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * attributed with the fully-described class name. For example:</p> 2023f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <pre> 2024f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * {@code 2025f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <changeBounds> 2026f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <pathMotion class="my.app.transition.MyPathMotion"/> 2027f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * </changeBounds> 2028f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * } 2029f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * </pre> 2030f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <p>or</p> 2031f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <pre> 2032f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * {@code 2033f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <changeBounds> 2034f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <arcMotion android:minimumHorizontalAngle="15" 2035f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * android:minimumVerticalAngle="0" android:maximumAngle="90"/> 2036f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * </changeBounds> 2037f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * } 2038f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * </pre> 2039f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * 2040ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * @param pathMotion Algorithm object to use for determining how to interpolate in two 2041ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * dimensions. If null, a straight-path algorithm will be used. 2042f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * @see android.transition.ArcMotion 2043f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * @see PatternPathMotion 2044f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * @see android.transition.PathMotion 2045ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount */ 2046ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount public void setPathMotion(PathMotion pathMotion) { 2047ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount if (pathMotion == null) { 2048ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount mPathMotion = STRAIGHT_PATH_MOTION; 2049ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } else { 2050ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount mPathMotion = pathMotion; 2051ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 2052ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 2053ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 2054ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount /** 2055ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * Returns the algorithm object used to interpolate along two dimensions. This is typically 2056ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * used to determine the View motion between two points. 2057ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * 2058f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <p> 2059f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * When describing in XML, use a nested XML tag for the path motion. It can be one of 2060f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * the built-in tags <code>arcMotion</code> or <code>patternPathMotion</code> or it can 2061f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * be a custom PathMotion using <code>pathMotion</code> with the <code>class</code> 2062f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * attributed with the fully-described class name. For example:</p> 2063f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <pre> 2064f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * {@code 2065f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <changeBounds> 2066f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <pathMotion class="my.app.transition.MyPathMotion"/> 2067f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * </changeBounds>} 2068f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * </pre> 2069f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <p>or</p> 2070f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <pre> 2071f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * {@code 2072f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <changeBounds> 2073f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * <arcMotion android:minimumHorizontalAngle="15" 2074f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * android:minimumVerticalAngle="0" 2075f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * android:maximumAngle="90"/> 2076f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * </changeBounds>} 2077f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * </pre> 2078f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * 2079ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount * @return The algorithm object used to interpolate along two dimensions. 2080f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * @see android.transition.ArcMotion 2081f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * @see PatternPathMotion 2082f9557619a7643c971e64e5b35583476202e77b7bGeorge Mount * @see android.transition.PathMotion 2083ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount */ 2084ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount public PathMotion getPathMotion() { 2085ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount return mPathMotion; 2086ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount } 2087ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount 2088ecd857be3946283ebb4306e2c03ae70f5c5bb152George Mount /** 2089d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Sets the method for determining Animator start delays. 2090d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * When a Transition affects several Views like {@link android.transition.Explode} or 2091d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect 2092d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * such that the Animator start delay depends on position of the View. The 2093d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * TransitionPropagation specifies how the start delays are calculated. 2094d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param transitionPropagation The class used to determine the start delay of 2095d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Animators created by this Transition. A null value 2096d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * indicates that no delay should be used. 2097d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 2098d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public void setPropagation(TransitionPropagation transitionPropagation) { 2099d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mPropagation = transitionPropagation; 2100d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2101d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 2102d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 2103d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Returns the {@link android.transition.TransitionPropagation} used to calculate Animator start 2104d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * delays. 2105d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * When a Transition affects several Views like {@link android.transition.Explode} or 2106d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Slide}, there may be a desire to have a "wave-front" effect 2107d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * such that the Animator start delay depends on position of the View. The 2108d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * TransitionPropagation specifies how the start delays are calculated. 2109d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return the {@link android.transition.TransitionPropagation} used to calculate Animator start 2110d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * delays. This is null by default. 2111d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 2112d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public TransitionPropagation getPropagation() { 2113d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return mPropagation; 2114d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2115d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 2116d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 2117d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Captures TransitionPropagation values for the given view and the 2118d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * hierarchy underneath it. 2119d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 2120d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount void capturePropagationValues(TransitionValues transitionValues) { 212131a217290cf376d0573fc36e21c8940987485019George Mount if (mPropagation != null && !transitionValues.values.isEmpty()) { 2122d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount String[] propertyNames = mPropagation.getPropagationProperties(); 2123d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (propertyNames == null) { 2124d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount return; 2125d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2126d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount boolean containsAll = true; 2127d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount for (int i = 0; i < propertyNames.length; i++) { 2128d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (!transitionValues.values.containsKey(propertyNames[i])) { 2129d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount containsAll = false; 2130d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount break; 2131d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2132d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2133d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount if (!containsAll) { 2134d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount mPropagation.captureValues(transitionValues); 2135d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2136d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2137d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2138d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 2139d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase Transition setSceneRoot(ViewGroup sceneRoot) { 21406ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase mSceneRoot = sceneRoot; 2141d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase return this; 21426ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 21436ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 2144b7a7fc9d233bad507ce893882352618b13647058Chet Haase void setCanRemoveViews(boolean canRemoveViews) { 2145b7a7fc9d233bad507ce893882352618b13647058Chet Haase mCanRemoveViews = canRemoveViews; 2146b7a7fc9d233bad507ce893882352618b13647058Chet Haase } 2147b7a7fc9d233bad507ce893882352618b13647058Chet Haase 21480a778eda690a66173733a63622886e888d405c45George Mount public boolean canRemoveViews() { 21490a778eda690a66173733a63622886e888d405c45George Mount return mCanRemoveViews; 21500a778eda690a66173733a63622886e888d405c45George Mount } 21510a778eda690a66173733a63622886e888d405c45George Mount 2152d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount /** 2153d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount * Sets the shared element names -- a mapping from a name at the start state to 2154d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount * a different name at the end state. 2155d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount * @hide 2156d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount */ 2157d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount public void setNameOverrides(ArrayMap<String, String> overrides) { 2158d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount mNameOverrides = overrides; 2159d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 2160d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount 2161d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount /** @hide */ 2162d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount public ArrayMap<String, String> getNameOverrides() { 2163d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount return mNameOverrides; 2164d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount } 2165d4c3c91dd0757eec9703ef90ea4c5a7ee99f18caGeorge Mount 2166b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount /** @hide */ 2167b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount public void forceVisibility(int visibility, boolean isStartValue) {} 2168b5ef7f8c6d4629b2998de6c0b27bc1a4779b3e49George Mount 2169faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 2170faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public String toString() { 2171faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return toString(""); 2172faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2173faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 21746ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase @Override 21756ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase public Transition clone() { 21766ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase Transition clone = null; 21776ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase try { 21786ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase clone = (Transition) super.clone(); 2179199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase clone.mAnimators = new ArrayList<Animator>(); 21807660d121b2ef21164ed33e6091e5dd50f5d0f939Chet Haase clone.mStartValues = new TransitionValuesMaps(); 21817660d121b2ef21164ed33e6091e5dd50f5d0f939Chet Haase clone.mEndValues = new TransitionValuesMaps(); 21824d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount clone.mStartValuesList = null; 21834d1ecf5daf6ad0b5420f3f3657e2cbaeea630240George Mount clone.mEndValuesList = null; 21846ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } catch (CloneNotSupportedException e) {} 21856ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 21866ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase return clone; 21876ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase } 21886ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase 2189199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 2190199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Returns the name of this Transition. This name is used internally to distinguish 2191199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * between different transitions to determine when interrupting transitions overlap. 2192d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * For example, a ChangeBounds running on the same target view as another ChangeBounds 2193d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * should determine whether the old transition is animating to different end values 2194d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * and should be canceled in favor of the new transition. 2195199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 2196199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * <p>By default, a Transition's name is simply the value of {@link Class#getName()}, 2197199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * but subclasses are free to override and return something different.</p> 2198199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 2199199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @return The name of this transition. 2200199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 2201199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public String getName() { 2202199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase return mName; 2203199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 2204199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2205faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase String toString(String indent) { 2206faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase String result = indent + getClass().getSimpleName() + "@" + 2207faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase Integer.toHexString(hashCode()) + ": "; 2208c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mDuration != -1) { 2209c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "dur(" + mDuration + ") "; 2210c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 2211c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mStartDelay != -1) { 2212c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "dly(" + mStartDelay + ") "; 2213c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 2214c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (mInterpolator != null) { 2215c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "interp(" + mInterpolator + ") "; 2216c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 2217d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0 || mTargets.size() > 0) { 2218c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += "tgts("; 2219d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargetIds.size() > 0) { 2220d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargetIds.size(); ++i) { 2221c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (i > 0) { 2222c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ", "; 2223c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 2224d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase result += mTargetIds.get(i); 2225faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2226faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2227d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase if (mTargets.size() > 0) { 2228d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase for (int i = 0; i < mTargets.size(); ++i) { 2229c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase if (i > 0) { 2230c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ", "; 2231c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase } 2232d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase result += mTargets.get(i); 2233faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2234faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2235c43524f3869cc0d36974fce61986017093f2ecd2Chet Haase result += ")"; 2236faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2237faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase return result; 2238faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2239faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2240faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 2241faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * A transition listener receives notifications from a transition. 2242199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notifications indicate transition lifecycle events. 2243faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 2244faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public static interface TransitionListener { 2245faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 2246faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the start of the transition. 2247faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 2248faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The started transition. 2249faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 2250faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionStart(Transition transition); 2251faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2252faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 2253faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the end of the transition. Canceled transitions 2254faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * will always notify listeners of both the cancellation and end 2255199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * events. That is, {@link #onTransitionEnd(Transition)} is always called, 2256faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * regardless of whether the transition was canceled or played 2257faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * through to completion. 2258faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 2259faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The transition which reached its end. 2260faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 2261faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionEnd(Transition transition); 2262faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2263faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 2264faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Notification about the cancellation of the transition. 2265d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that cancel may be called by a parent {@link TransitionSet} on 2266199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 2267199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state on target objects which was set at 2268d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 2269d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimator()} time. 2270faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 2271faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @param transition The transition which was canceled. 2272faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */ 2273faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase void onTransitionCancel(Transition transition); 2274199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2275199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 2276199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notification when a transition is paused. 2277d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that createAnimator() may be called by a parent {@link TransitionSet} on 2278199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 2279199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state on target objects which was set at 2280d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * {@link #createAnimator(android.view.ViewGroup, TransitionValues, TransitionValues) 2281d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * createAnimator()} time. 2282199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 2283199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @param transition The transition which was paused. 2284199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 2285199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase void onTransitionPause(Transition transition); 2286199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2287199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 2288199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Notification when a transition is resumed. 2289d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * Note that resume() may be called by a parent {@link TransitionSet} on 2290199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * a child transition which has not yet started. This allows the child 2291199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * transition to restore state which may have changed in an earlier call 2292199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * to {@link #onTransitionPause(Transition)}. 2293199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * 2294199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * @param transition The transition which was resumed. 2295199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 2296199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase void onTransitionResume(Transition transition); 2297faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2298faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2299faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase /** 2300faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * Utility adapter class to avoid having to override all three methods 2301faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * whenever someone just wants to listen for a single event. 2302faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * 2303faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * @hide 2304faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase * */ 2305faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public static class TransitionListenerAdapter implements TransitionListener { 2306faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 2307faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionStart(Transition transition) { 2308faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2309faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2310faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 2311faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionEnd(Transition transition) { 2312faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2313faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2314faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase @Override 2315faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase public void onTransitionCancel(Transition transition) { 2316faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2317199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2318199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase @Override 2319199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void onTransitionPause(Transition transition) { 2320199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 2321199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 2322199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase @Override 2323199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase public void onTransitionResume(Transition transition) { 2324199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 2325faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase } 2326faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase 2327199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase /** 2328199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * Holds information about each animator used when a new transition starts 2329199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * while other transitions are still running to determine whether a running 2330199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * animation should be canceled or a new animation noop'd. The structure holds 2331199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * information about the state that an animation is going to, to be compared to 2332199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase * end state of a new animation. 23330a778eda690a66173733a63622886e888d405c45George Mount * @hide 2334199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase */ 23350a778eda690a66173733a63622886e888d405c45George Mount public static class AnimationInfo { 23360a778eda690a66173733a63622886e888d405c45George Mount public View view; 2337199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase String name; 2338199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase TransitionValues values; 2339cf68aad3164303df59b2a669d186a94533c9c743George Mount WindowId windowId; 23404c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount Transition transition; 2341199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase 23424c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount AnimationInfo(View view, String name, Transition transition, 23434c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount WindowId windowId, TransitionValues values) { 2344199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.view = view; 2345199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.name = name; 2346199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase this.values = values; 2347cf68aad3164303df59b2a669d186a94533c9c743George Mount this.windowId = windowId; 23484c20ea29728a80b42487b3ba1600d11d5ea47bccGeorge Mount this.transition = transition; 2349199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 2350199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase } 2351ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 2352ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 2353ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Utility class for managing typed ArrayLists efficiently. In particular, this 2354ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * can be useful for lists that we don't expect to be used often (eg, the exclude 2355ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * lists), so we'd like to keep them nulled out by default. This causes the code to 2356ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * become tedious, with constant null checks, code to allocate when necessary, 2357ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * and code to null out the reference when the list is empty. This class encapsulates 2358ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * all of that functionality into simple add()/remove() methods which perform the 2359ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * necessary checks, allocation/null-out as appropriate, and return the 2360ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * resulting list. 2361ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 2362ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase private static class ArrayListManager { 2363ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 2364ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 2365ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Add the specified item to the list, returning the resulting list. 2366ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * The returned list can either the be same list passed in or, if that 2367ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list was null, the new list that was created. 2368ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * 2369ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Note that the list holds unique items; if the item already exists in the 2370ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list, the list is not modified. 2371ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 2372ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase static <T> ArrayList<T> add(ArrayList<T> list, T item) { 2373ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list == null) { 2374ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = new ArrayList<T>(); 2375ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2376ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (!list.contains(item)) { 2377ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list.add(item); 2378ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2379ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 2380ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2381ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 2382ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase /** 2383ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * Remove the specified item from the list, returning the resulting list. 2384ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * The returned list can either the be same list passed in or, if that 2385ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase * list becomes empty as a result of the remove(), the new list was created. 2386ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase */ 2387ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase static <T> ArrayList<T> remove(ArrayList<T> list, T item) { 2388ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list != null) { 2389ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list.remove(item); 2390ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase if (list.isEmpty()) { 2391ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase list = null; 2392ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2393ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2394ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase return list; 2395ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2396ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase } 2397ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase 2398d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 2399d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Class to get the epicenter of Transition. Use 2400d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #setEpicenterCallback(android.transition.Transition.EpicenterCallback)} to 2401d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * set the callback used to calculate the epicenter of the Transition. Override 2402d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link #getEpicenter()} to return the rectangular region in screen coordinates of 2403d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * the epicenter of the transition. 2404d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @see #setEpicenterCallback(android.transition.Transition.EpicenterCallback) 2405d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 2406d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount public static abstract class EpicenterCallback { 2407d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount 2408d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount /** 2409d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * Implementers must override to return the epicenter of the Transition in screen 2410d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * coordinates. Transitions like {@link android.transition.Explode} depend upon 2411d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * an epicenter for the Transition. In Explode, Views move toward or away from the 2412d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * center of the epicenter Rect along the vector between the epicenter and the center 2413d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * of the View appearing and disappearing. Some Transitions, such as 2414d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * {@link android.transition.Fade} pay no attention to the epicenter. 2415d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * 2416d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @param transition The transition for which the epicenter applies. 2417d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * @return The Rect region of the epicenter of <code>transition</code> or null if 2418d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount * there is no epicenter. 2419d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount */ 2420dc21d3b2804c24fe29ec860796d11185901364c4George Mount public abstract Rect onGetEpicenter(Transition transition); 2421d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount } 2422faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase} 2423