TransitionSet.java revision 30da61d477bcb6cc7718f9516c444359352fe148
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
19d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haaseimport android.animation.TimeInterpolator;
20d6107a3170df61d9e776fcd5666acfc9135c6f16George Mountimport android.graphics.Rect;
21faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.util.AndroidRuntimeException;
22d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haaseimport android.view.View;
23faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport android.view.ViewGroup;
24faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
25faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haaseimport java.util.ArrayList;
26faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
27faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase/**
28d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * A TransitionSet is a parent of child transitions (including other
29d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * TransitionSets). Using TransitionSets enables more complex
30d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * choreography of transitions, where some sets play {@link #ORDERING_TOGETHER} and
31d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * others play {@link #ORDERING_SEQUENTIAL}. For example, {@link AutoTransition}
32d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * uses a TransitionSet to sequentially play a Fade(Fade.OUT), followed by
33d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase * a {@link ChangeBounds}, followed by a Fade(Fade.OUT) transition.
34aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase *
35aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * <p>A TransitionSet can be described in a resource file by using the
36aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * tag <code>transitionSet</code>, along with the standard
37aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * attributes of {@link android.R.styleable#TransitionSet} and
38aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * {@link android.R.styleable#Transition}. Child transitions of the
39aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * TransitionSet object can be loaded by adding those child tags inside the
40aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * enclosing <code>transitionSet</code> tag. For example, the following xml
41aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * describes a TransitionSet that plays a Fade and then a ChangeBounds
42aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * transition on the affected view targets:</p>
43aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * <pre>
44aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase *     &lt;transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
45aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase *             android:ordering="sequential"&gt;
46aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase *         &lt;fade/&gt;
47aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase *         &lt;changeBounds/&gt;
48aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase *     &lt;/transitionSet&gt;
49aafc91c05acfb2d5a95f46f27e1deb2dfaa15c32Chet Haase * </pre>
50faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase */
51d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haasepublic class TransitionSet extends Transition {
52faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
53faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    ArrayList<Transition> mTransitions = new ArrayList<Transition>();
54faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    private boolean mPlayTogether = true;
55faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    int mCurrentListeners;
56faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    boolean mStarted = false;
57faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
58faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
59d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * A flag used to indicate that the child transitions of this set
60faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * should all start at the same time.
61faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
62d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public static final int ORDERING_TOGETHER = 0;
63faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
64d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * A flag used to indicate that the child transitions of this set should
65faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * play in sequence; when one child transition ends, the next child
66faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * transition begins. Note that a transition does not end until all
67faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * instances of it (which are playing on all applicable targets of the
68faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * transition) end.
69faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
70d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public static final int ORDERING_SEQUENTIAL = 1;
71faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
72faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
73d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * Constructs an empty transition set. Add child transitions to the
74d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * set by calling {@link #addTransition(Transition)} )}. By default,
75d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * child transitions will play {@link #ORDERING_TOGETHER together}.
76faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
77d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet() {
78faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    }
79faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
80faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
81d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * Sets the play order of this set's child transitions.
82faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     *
83d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * @param ordering {@link #ORDERING_TOGETHER} to play this set's child
84d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * transitions together, {@link #ORDERING_SEQUENTIAL} to play the child
85faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * transitions in sequence.
86d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * @return This transitionSet object.
87faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
88d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet setOrdering(int ordering) {
89faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        switch (ordering) {
90d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            case ORDERING_SEQUENTIAL:
91faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                mPlayTogether = false;
92faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                break;
93d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            case ORDERING_TOGETHER:
94faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                mPlayTogether = true;
95faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                break;
96faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            default:
97d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase                throw new AndroidRuntimeException("Invalid parameter for TransitionSet " +
98faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                        "ordering: " + ordering);
99faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        }
100d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return this;
101faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    }
102faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
103faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
104d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * Returns the ordering of this TransitionSet. By default, the value is
105d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * {@link #ORDERING_TOGETHER}.
106d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     *
107d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * @return {@link #ORDERING_TOGETHER} if child transitions will play at the same
108d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * time, {@link #ORDERING_SEQUENTIAL} if they will play in sequence.
109faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     *
110d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * @see #setOrdering(int)
111faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
112d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public int getOrdering() {
113d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return mPlayTogether ? ORDERING_TOGETHER : ORDERING_SEQUENTIAL;
114d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
115d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
116d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    /**
117d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * Adds child transition to this set. The order in which this child transition
118d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * is added relative to other child transitions that are added, in addition to
119d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * the {@link #getOrdering() ordering} property, determines the
120d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * order in which the transitions are started.
121d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     *
122d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * <p>If this transitionSet has a {@link #getDuration() duration} set on it, the
123d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * child transition will inherit that duration. Transitions are assumed to have
124d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * a maximum of one transitionSet parent.</p>
125d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     *
126d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * @param transition A non-null child transition to be added to this set.
127d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * @return This transitionSet object.
128d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     */
129d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet addTransition(Transition transition) {
130d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        if (transition != null) {
131d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            mTransitions.add(transition);
132d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            transition.mParent = this;
133d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            if (mDuration >= 0) {
134d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase                transition.setDuration(mDuration);
135faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            }
136faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        }
137d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return this;
138faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    }
139faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
140faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
141d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * Setting a non-negative duration on a TransitionSet causes all of the child
142867a86613d4152a93423300f83597300e6ebeebeChet Haase     * transitions (current and future) to inherit this duration.
143867a86613d4152a93423300f83597300e6ebeebeChet Haase     *
144867a86613d4152a93423300f83597300e6ebeebeChet Haase     * @param duration The length of the animation, in milliseconds.
145d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * @return This transitionSet object.
146867a86613d4152a93423300f83597300e6ebeebeChet Haase     */
147867a86613d4152a93423300f83597300e6ebeebeChet Haase    @Override
148d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet setDuration(long duration) {
149867a86613d4152a93423300f83597300e6ebeebeChet Haase        super.setDuration(duration);
150867a86613d4152a93423300f83597300e6ebeebeChet Haase        if (mDuration >= 0) {
151867a86613d4152a93423300f83597300e6ebeebeChet Haase            int numTransitions = mTransitions.size();
152867a86613d4152a93423300f83597300e6ebeebeChet Haase            for (int i = 0; i < numTransitions; ++i) {
153867a86613d4152a93423300f83597300e6ebeebeChet Haase                mTransitions.get(i).setDuration(duration);
154867a86613d4152a93423300f83597300e6ebeebeChet Haase            }
155867a86613d4152a93423300f83597300e6ebeebeChet Haase        }
156867a86613d4152a93423300f83597300e6ebeebeChet Haase        return this;
157867a86613d4152a93423300f83597300e6ebeebeChet Haase    }
158867a86613d4152a93423300f83597300e6ebeebeChet Haase
159d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    @Override
160d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet setStartDelay(long startDelay) {
161d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return (TransitionSet) super.setStartDelay(startDelay);
162d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
163d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
164d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    @Override
165d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet setInterpolator(TimeInterpolator interpolator) {
166d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return (TransitionSet) super.setInterpolator(interpolator);
167d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
168d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
169d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    @Override
170d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet addTarget(View target) {
171d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return (TransitionSet) super.addTarget(target);
172d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
173d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
174d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    @Override
175ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase    public TransitionSet addTarget(int targetId) {
176ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase        return (TransitionSet) super.addTarget(targetId);
177d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
178d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
179d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    @Override
180d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet addListener(TransitionListener listener) {
181d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return (TransitionSet) super.addListener(listener);
182d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
183d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
184d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    @Override
185ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase    public TransitionSet removeTarget(int targetId) {
186ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase        return (TransitionSet) super.removeTarget(targetId);
187d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
188d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
189d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    @Override
190d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet removeTarget(View target) {
191d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return (TransitionSet) super.removeTarget(target);
192d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
193d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
194d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    @Override
195d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet removeListener(TransitionListener listener) {
196d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return (TransitionSet) super.removeListener(listener);
197d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
198d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
199867a86613d4152a93423300f83597300e6ebeebeChet Haase    /**
200d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * Removes the specified child transition from this set.
201faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     *
202faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * @param transition The transition to be removed.
203d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * @return This transitionSet object.
204faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
205d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet removeTransition(Transition transition) {
206faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        mTransitions.remove(transition);
2076ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        transition.mParent = null;
208d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return this;
209faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    }
210faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
211faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
212faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * Sets up listeners for each of the child transitions. This is used to
213d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * determine when this transition set is finished (all child transitions
214faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * must finish first).
215faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
216faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    private void setupStartEndListeners() {
217d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        TransitionSetListener listener = new TransitionSetListener(this);
218faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        for (Transition childTransition : mTransitions) {
2196ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase            childTransition.addListener(listener);
220faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        }
221faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        mCurrentListeners = mTransitions.size();
222faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    }
223faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
224faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
225faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * This listener is used to detect when all child transitions are done, at
226d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase     * which point this transition set is also done.
227faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
228d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    static class TransitionSetListener extends TransitionListenerAdapter {
229d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        TransitionSet mTransitionSet;
230d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        TransitionSetListener(TransitionSet transitionSet) {
231d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            mTransitionSet = transitionSet;
2326ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        }
233faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        @Override
234faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        public void onTransitionStart(Transition transition) {
235d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            if (!mTransitionSet.mStarted) {
236d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase                mTransitionSet.start();
237d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase                mTransitionSet.mStarted = true;
238faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            }
239faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        }
240faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
241faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        @Override
242faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        public void onTransitionEnd(Transition transition) {
243d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            --mTransitionSet.mCurrentListeners;
244d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            if (mTransitionSet.mCurrentListeners == 0) {
245faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                // All child trans
246d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase                mTransitionSet.mStarted = false;
247d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase                mTransitionSet.end();
248faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            }
249faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            transition.removeListener(this);
250faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        }
2516ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase    }
252faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
253faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
254faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * @hide
255faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
256faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    @Override
257d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
2586ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase            TransitionValuesMaps endValues) {
2598c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount        startValues = removeExcludes(startValues);
2608c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount        endValues = removeExcludes(endValues);
261faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        for (Transition childTransition : mTransitions) {
262d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            childTransition.createAnimators(sceneRoot, startValues, endValues);
263faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        }
264faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    }
265faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
2668c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount    private TransitionValuesMaps removeExcludes(TransitionValuesMaps values) {
2678c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount        if (mTargetIds.isEmpty() && mTargetIdExcludes == null && mTargetTypeExcludes == null
2688c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount                && mTargets.isEmpty()) {
2698c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount            return values;
2708c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount        }
2718c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount        TransitionValuesMaps included = new TransitionValuesMaps();
2728c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount        int numValues = values.viewValues.size();
2738c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount        for (int i = 0; i < numValues; i++) {
2748c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount            View view = values.viewValues.keyAt(i);
27530da61d477bcb6cc7718f9516c444359352fe148George Mount            if (isValidTarget(view)) {
27630da61d477bcb6cc7718f9516c444359352fe148George Mount                addViewValues(included, view, values.viewValues.valueAt(i));
2778c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount            }
2788c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount        }
2798c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount        return included;
2808c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount    }
2818c0ceb34c3de5153dad162be719e2933c56886aeGeorge Mount
282faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    /**
283faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     * @hide
284faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase     */
285faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    @Override
286d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    protected void runAnimators() {
287faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        setupStartEndListeners();
288faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        if (!mPlayTogether) {
289faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            // Setup sequence with listeners
290faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            // TODO: Need to add listeners in such a way that we can remove them later if canceled
291faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            for (int i = 1; i < mTransitions.size(); ++i) {
292faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                Transition previousTransition = mTransitions.get(i - 1);
293faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                final Transition nextTransition = mTransitions.get(i);
294faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                previousTransition.addListener(new TransitionListenerAdapter() {
295faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                    @Override
296faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                    public void onTransitionEnd(Transition transition) {
297d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase                        nextTransition.runAnimators();
298faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                        transition.removeListener(this);
299faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                    }
300faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase                });
301faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            }
302faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            Transition firstTransition = mTransitions.get(0);
303faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            if (firstTransition != null) {
304d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase                firstTransition.runAnimators();
305faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            }
306faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        } else {
307faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            for (Transition childTransition : mTransitions) {
308d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase                childTransition.runAnimators();
309faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            }
310faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        }
311faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    }
312faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
313faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    @Override
314d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public void captureStartValues(TransitionValues transitionValues) {
31530da61d477bcb6cc7718f9516c444359352fe148George Mount        if (isValidTarget(transitionValues.view)) {
316ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase            for (Transition childTransition : mTransitions) {
31730da61d477bcb6cc7718f9516c444359352fe148George Mount                if (childTransition.isValidTarget(transitionValues.view)) {
318ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase                    childTransition.captureStartValues(transitionValues);
319ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase                }
320d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase            }
321d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        }
322d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    }
323d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase
324d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    @Override
325d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public void captureEndValues(TransitionValues transitionValues) {
32630da61d477bcb6cc7718f9516c444359352fe148George Mount        if (isValidTarget(transitionValues.view)) {
327ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase            for (Transition childTransition : mTransitions) {
32830da61d477bcb6cc7718f9516c444359352fe148George Mount                if (childTransition.isValidTarget(transitionValues.view)) {
329ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase                    childTransition.captureEndValues(transitionValues);
330ff58f92a0a77ad849ba714b5adac96790eca0048Chet Haase                }
331faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            }
332faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        }
333faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    }
334faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
335d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount    @Override
336d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount    void capturePropagationValues(TransitionValues transitionValues) {
337d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        super.capturePropagationValues(transitionValues);
338d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        int numTransitions = mTransitions.size();
339d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        for (int i = 0; i < numTransitions; ++i) {
340d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount            mTransitions.get(i).capturePropagationValues(transitionValues);
341d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        }
342d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount    }
343d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount
344199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    /** @hide */
345faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    @Override
346cf68aad3164303df59b2a669d186a94533c9c743George Mount    public void pause(View sceneRoot) {
347cf68aad3164303df59b2a669d186a94533c9c743George Mount        super.pause(sceneRoot);
348e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase        int numTransitions = mTransitions.size();
349e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase        for (int i = 0; i < numTransitions; ++i) {
350cf68aad3164303df59b2a669d186a94533c9c743George Mount            mTransitions.get(i).pause(sceneRoot);
351199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase        }
352199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    }
353199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase
354199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    /** @hide */
355199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    @Override
356cf68aad3164303df59b2a669d186a94533c9c743George Mount    public void resume(View sceneRoot) {
357cf68aad3164303df59b2a669d186a94533c9c743George Mount        super.resume(sceneRoot);
358199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase        int numTransitions = mTransitions.size();
359199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase        for (int i = 0; i < numTransitions; ++i) {
360cf68aad3164303df59b2a669d186a94533c9c743George Mount            mTransitions.get(i).resume(sceneRoot);
361199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase        }
362199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    }
363199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase
364d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    /** @hide */
365199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    @Override
366199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase    protected void cancel() {
367199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase        super.cancel();
368199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase        int numTransitions = mTransitions.size();
369199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase        for (int i = 0; i < numTransitions; ++i) {
370199acdfcc98e852975dd7edfbcb822ba5e73146fChet Haase            mTransitions.get(i).cancel();
371e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase        }
372e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase    }
373e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase
374e9d32ea13ee14fc0eb4e45ca627ca77729d38bfeChet Haase    @Override
375d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    TransitionSet setSceneRoot(ViewGroup sceneRoot) {
3766ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        super.setSceneRoot(sceneRoot);
3776ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        int numTransitions = mTransitions.size();
3786ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        for (int i = 0; i < numTransitions; ++i) {
3796ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase            mTransitions.get(i).setSceneRoot(sceneRoot);
3806ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        }
381d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        return (TransitionSet) this;
3826ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase    }
3836ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase
3846ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase    @Override
385b7a7fc9d233bad507ce893882352618b13647058Chet Haase    void setCanRemoveViews(boolean canRemoveViews) {
386b7a7fc9d233bad507ce893882352618b13647058Chet Haase        super.setCanRemoveViews(canRemoveViews);
387b7a7fc9d233bad507ce893882352618b13647058Chet Haase        int numTransitions = mTransitions.size();
388b7a7fc9d233bad507ce893882352618b13647058Chet Haase        for (int i = 0; i < numTransitions; ++i) {
389b7a7fc9d233bad507ce893882352618b13647058Chet Haase            mTransitions.get(i).setCanRemoveViews(canRemoveViews);
390b7a7fc9d233bad507ce893882352618b13647058Chet Haase        }
391b7a7fc9d233bad507ce893882352618b13647058Chet Haase    }
392b7a7fc9d233bad507ce893882352618b13647058Chet Haase
393b7a7fc9d233bad507ce893882352618b13647058Chet Haase    @Override
394d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount    public void setPropagation(TransitionPropagation propagation) {
395d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        super.setPropagation(propagation);
396d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        int numTransitions = mTransitions.size();
397d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        for (int i = 0; i < numTransitions; ++i) {
398d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount            mTransitions.get(i).setPropagation(propagation);
399d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        }
400d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount    }
401d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount
402d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount    @Override
403d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount    public void setEpicenterCallback(EpicenterCallback epicenterCallback) {
404d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        super.setEpicenterCallback(epicenterCallback);
405d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        int numTransitions = mTransitions.size();
406d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        for (int i = 0; i < numTransitions; ++i) {
407d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount            mTransitions.get(i).setEpicenterCallback(epicenterCallback);
408d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount        }
409d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount    }
410d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount
411d6107a3170df61d9e776fcd5666acfc9135c6f16George Mount    @Override
412faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    String toString(String indent) {
413faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        String result = super.toString(indent);
414faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        for (int i = 0; i < mTransitions.size(); ++i) {
415faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase            result += "\n" + mTransitions.get(i).toString(indent + "  ");
416faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        }
417faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase        return result;
418faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase    }
419faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase
4206ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase    @Override
421d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase    public TransitionSet clone() {
422d82c8ac4db7091d2e976af4c89a1734465d20cd2Chet Haase        TransitionSet clone = (TransitionSet) super.clone();
4236ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        clone.mTransitions = new ArrayList<Transition>();
4246ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        int numTransitions = mTransitions.size();
4256ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        for (int i = 0; i < numTransitions; ++i) {
426c46181a963be736186ae29101625a05b5c1f0ba8Chet Haase            clone.addTransition((Transition) mTransitions.get(i).clone());
4276ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        }
4286ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase        return clone;
4296ebe3de331efd00ba23bc4191d4a82cfa4c39160Chet Haase    }
430faebd8f0795b7d275fb4e503533c8c0c4a9acc21Chet Haase}
431