/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.transition; import android.animation.TimeInterpolator; import android.content.Context; import android.content.res.TypedArray; import android.util.AndroidRuntimeException; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import com.android.internal.R; import java.util.ArrayList; /** * A TransitionSet is a parent of child transitions (including other * TransitionSets). Using TransitionSets enables more complex * choreography of transitions, where some sets play {@link #ORDERING_TOGETHER} and * others play {@link #ORDERING_SEQUENTIAL}. For example, {@link AutoTransition} * uses a TransitionSet to sequentially play a Fade(Fade.OUT), followed by * a {@link ChangeBounds}, followed by a Fade(Fade.OUT) transition. * *
A TransitionSet can be described in a resource file by using the
* tag transitionSet
, along with the standard
* attributes of {@link android.R.styleable#TransitionSet} and
* {@link android.R.styleable#Transition}. Child transitions of the
* TransitionSet object can be loaded by adding those child tags inside the
* enclosing transitionSet
tag. For example, the following xml
* describes a TransitionSet that plays a Fade and then a ChangeBounds
* transition on the affected view targets:
* <transitionSet xmlns:android="http://schemas.android.com/apk/res/android" * android:transitionOrdering="sequential"> * <fade/> * <changeBounds/> * </transitionSet> **/ public class TransitionSet extends Transition { ArrayList
If this transitionSet has a {@link #getDuration() duration} set on it, the * child transition will inherit that duration. Transitions are assumed to have * a maximum of one transitionSet parent.
* * @param transition A non-null child transition to be added to this set. * @return This transitionSet object. */ public TransitionSet addTransition(Transition transition) { if (transition != null) { mTransitions.add(transition); transition.mParent = this; if (mDuration >= 0) { transition.setDuration(mDuration); } } return this; } /** * Returns the number of child transitions in the TransitionSet. * * @return The number of child transitions in the TransitionSet. * @see #addTransition(Transition) * @see #getTransitionAt(int) */ public int getTransitionCount() { return mTransitions.size(); } /** * Returns the child Transition at the specified position in the TransitionSet. * * @param index The position of the Transition to retrieve. * @see #addTransition(Transition) * @see #getTransitionCount() */ public Transition getTransitionAt(int index) { if (index < 0 || index >= mTransitions.size()) { return null; } return mTransitions.get(index); } /** * Setting a non-negative duration on a TransitionSet causes all of the child * transitions (current and future) to inherit this duration. * * @param duration The length of the animation, in milliseconds. * @return This transitionSet object. */ @Override public TransitionSet setDuration(long duration) { super.setDuration(duration); if (mDuration >= 0 && mTransitions != null) { int numTransitions = mTransitions.size(); for (int i = 0; i < numTransitions; ++i) { mTransitions.get(i).setDuration(duration); } } return this; } @Override public TransitionSet setStartDelay(long startDelay) { return (TransitionSet) super.setStartDelay(startDelay); } @Override public TransitionSet setInterpolator(TimeInterpolator interpolator) { return (TransitionSet) super.setInterpolator(interpolator); } @Override public TransitionSet addTarget(View target) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).addTarget(target); } return (TransitionSet) super.addTarget(target); } @Override public TransitionSet addTarget(int targetId) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).addTarget(targetId); } return (TransitionSet) super.addTarget(targetId); } @Override public TransitionSet addTarget(String targetName) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).addTarget(targetName); } return (TransitionSet) super.addTarget(targetName); } @Override public TransitionSet addTarget(Class targetType) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).addTarget(targetType); } return (TransitionSet) super.addTarget(targetType); } @Override public TransitionSet addListener(TransitionListener listener) { return (TransitionSet) super.addListener(listener); } @Override public TransitionSet removeTarget(int targetId) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).removeTarget(targetId); } return (TransitionSet) super.removeTarget(targetId); } @Override public TransitionSet removeTarget(View target) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).removeTarget(target); } return (TransitionSet) super.removeTarget(target); } @Override public TransitionSet removeTarget(Class target) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).removeTarget(target); } return (TransitionSet) super.removeTarget(target); } @Override public TransitionSet removeTarget(String target) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).removeTarget(target); } return (TransitionSet) super.removeTarget(target); } @Override public Transition excludeTarget(View target, boolean exclude) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).excludeTarget(target, exclude); } return super.excludeTarget(target, exclude); } @Override public Transition excludeTarget(String targetName, boolean exclude) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).excludeTarget(targetName, exclude); } return super.excludeTarget(targetName, exclude); } @Override public Transition excludeTarget(int targetId, boolean exclude) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).excludeTarget(targetId, exclude); } return super.excludeTarget(targetId, exclude); } @Override public Transition excludeTarget(Class type, boolean exclude) { for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).excludeTarget(type, exclude); } return super.excludeTarget(type, exclude); } @Override public TransitionSet removeListener(TransitionListener listener) { return (TransitionSet) super.removeListener(listener); } @Override public void setPathMotion(PathMotion pathMotion) { super.setPathMotion(pathMotion); for (int i = 0; i < mTransitions.size(); i++) { mTransitions.get(i).setPathMotion(pathMotion); } } /** * Removes the specified child transition from this set. * * @param transition The transition to be removed. * @return This transitionSet object. */ public TransitionSet removeTransition(Transition transition) { mTransitions.remove(transition); transition.mParent = null; return this; } /** * Sets up listeners for each of the child transitions. This is used to * determine when this transition set is finished (all child transitions * must finish first). */ private void setupStartEndListeners() { TransitionSetListener listener = new TransitionSetListener(this); for (Transition childTransition : mTransitions) { childTransition.addListener(listener); } mCurrentListeners = mTransitions.size(); } /** * This listener is used to detect when all child transitions are done, at * which point this transition set is also done. */ static class TransitionSetListener extends TransitionListenerAdapter { TransitionSet mTransitionSet; TransitionSetListener(TransitionSet transitionSet) { mTransitionSet = transitionSet; } @Override public void onTransitionStart(Transition transition) { if (!mTransitionSet.mStarted) { mTransitionSet.start(); mTransitionSet.mStarted = true; } } @Override public void onTransitionEnd(Transition transition) { --mTransitionSet.mCurrentListeners; if (mTransitionSet.mCurrentListeners == 0) { // All child trans mTransitionSet.mStarted = false; mTransitionSet.end(); } transition.removeListener(this); } } /** * @hide */ @Override protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues, TransitionValuesMaps endValues, ArrayList