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