/*
 * Copyright (C) 2010 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.animation;

import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * This class enables automatic animations on layout changes in ViewGroup objects. To enable
 * transitions for a layout container, create a LayoutTransition object and set it on any
 * ViewGroup by calling {@link ViewGroup#setLayoutTransition(LayoutTransition)}. This will cause
 * default animations to run whenever items are added to or removed from that container. To specify
 * custom animations, use the {@link LayoutTransition#setAnimator(int, Animator)
 * setAnimator()} method.
 *
 * <p>One of the core concepts of these transition animations is that there are two types of
 * changes that cause the transition and four different animations that run because of
 * those changes. The changes that trigger the transition are items being added to a container
 * (referred to as an "appearing" transition) or removed from a container (also known as
 * "disappearing"). Setting the visibility of views (between GONE and VISIBLE) will trigger
 * the same add/remove logic. The animations that run due to those events are one that animates
 * items being added, one that animates items being removed, and two that animate the other
 * items in the container that change due to the add/remove occurrence. Users of
 * the transition may want different animations for the changing items depending on whether
 * they are changing due to an appearing or disappearing event, so there is one animation for
 * each of these variations of the changing event. Most of the API of this class is concerned
 * with setting up the basic properties of the animations used in these four situations,
 * or with setting up custom animations for any or all of the four.</p>
 *
 * <p>By default, the DISAPPEARING animation begins immediately, as does the CHANGE_APPEARING
 * animation. The other animations begin after a delay that is set to the default duration
 * of the animations. This behavior facilitates a sequence of animations in transitions as
 * follows: when an item is being added to a layout, the other children of that container will
 * move first (thus creating space for the new item), then the appearing animation will run to
 * animate the item being added. Conversely, when an item is removed from a container, the
 * animation to remove it will run first, then the animations of the other children in the
 * layout will run (closing the gap created in the layout when the item was removed). If this
 * default choreography behavior is not desired, the {@link #setDuration(int, long)} and
 * {@link #setStartDelay(int, long)} of any or all of the animations can be changed as
 * appropriate.</p>
 *
 * <p>The animations specified for the transition, both the defaults and any custom animations
 * set on the transition object, are templates only. That is, these animations exist to hold the
 * basic animation properties, such as the duration, start delay, and properties being animated.
 * But the actual target object, as well as the start and end values for those properties, are
 * set automatically in the process of setting up the transition each time it runs. Each of the
 * animations is cloned from the original copy and the clone is then populated with the dynamic
 * values of the target being animated (such as one of the items in a layout container that is
 * moving as a result of the layout event) as well as the values that are changing (such as the
 * position and size of that object). The actual values that are pushed to each animation
 * depends on what properties are specified for the animation. For example, the default
 * CHANGE_APPEARING animation animates the <code>left</code>, <code>top</code>, <code>right</code>,
 * <code>bottom</code>, <code>scrollX</code>, and <code>scrollY</code> properties.
 * Values for these properties are updated with the pre- and post-layout
 * values when the transition begins. Custom animations will be similarly populated with
 * the target and values being animated, assuming they use ObjectAnimator objects with
 * property names that are known on the target object.</p>
 *
 * <p>This class, and the associated XML flag for containers, animateLayoutChanges="true",
 * provides a simple utility meant for automating changes in straightforward situations.
 * Using LayoutTransition at multiple levels of a nested view hierarchy may not work due to the
 * interrelationship of the various levels of layout. Also, a container that is being scrolled
 * at the same time as items are being added or removed is probably not a good candidate for
 * this utility, because the before/after locations calculated by LayoutTransition
 * may not match the actual locations when the animations finish due to the container
 * being scrolled as the animations are running. You can work around that
 * particular issue by disabling the 'changing' animations by setting the CHANGE_APPEARING
 * and CHANGE_DISAPPEARING animations to null, and setting the startDelay of the
 * other animations appropriately.</p>
 */
public class LayoutTransition {

    /**
     * A flag indicating the animation that runs on those items that are changing
     * due to a new item appearing in the container.
     */
    public static final int CHANGE_APPEARING = 0;

    /**
     * A flag indicating the animation that runs on those items that are changing
     * due to an item disappearing from the container.
     */
    public static final int CHANGE_DISAPPEARING = 1;

    /**
     * A flag indicating the animation that runs on those items that are appearing
     * in the container.
     */
    public static final int APPEARING = 2;

    /**
     * A flag indicating the animation that runs on those items that are disappearing
     * from the container.
     */
    public static final int DISAPPEARING = 3;

    /**
     * A flag indicating the animation that runs on those items that are changing
     * due to a layout change not caused by items being added to or removed
     * from the container. This transition type is not enabled by default; it can be
     * enabled via {@link #enableTransitionType(int)}.
     */
    public static final int CHANGING = 4;

    /**
     * Private bit fields used to set the collection of enabled transition types for
     * mTransitionTypes.
     */
    private static final int FLAG_APPEARING             = 0x01;
    private static final int FLAG_DISAPPEARING          = 0x02;
    private static final int FLAG_CHANGE_APPEARING      = 0x04;
    private static final int FLAG_CHANGE_DISAPPEARING   = 0x08;
    private static final int FLAG_CHANGING              = 0x10;

    /**
     * These variables hold the animations that are currently used to run the transition effects.
     * These animations are set to defaults, but can be changed to custom animations by
     * calls to setAnimator().
     */
    private Animator mDisappearingAnim = null;
    private Animator mAppearingAnim = null;
    private Animator mChangingAppearingAnim = null;
    private Animator mChangingDisappearingAnim = null;
    private Animator mChangingAnim = null;

    /**
     * These are the default animations, defined in the constructor, that will be used
     * unless the user specifies custom animations.
     */
    private static ObjectAnimator defaultChange;
    private static ObjectAnimator defaultChangeIn;
    private static ObjectAnimator defaultChangeOut;
    private static ObjectAnimator defaultFadeIn;
    private static ObjectAnimator defaultFadeOut;

    /**
     * The default duration used by all animations.
     */
    private static long DEFAULT_DURATION = 300;

    /**
     * The durations of the different animations
     */
    private long mChangingAppearingDuration = DEFAULT_DURATION;
    private long mChangingDisappearingDuration = DEFAULT_DURATION;
    private long mChangingDuration = DEFAULT_DURATION;
    private long mAppearingDuration = DEFAULT_DURATION;
    private long mDisappearingDuration = DEFAULT_DURATION;

    /**
     * The start delays of the different animations. Note that the default behavior of
     * the appearing item is the default duration, since it should wait for the items to move
     * before fading it. Same for the changing animation when disappearing; it waits for the item
     * to fade out before moving the other items.
     */
    private long mAppearingDelay = DEFAULT_DURATION;
    private long mDisappearingDelay = 0;
    private long mChangingAppearingDelay = 0;
    private long mChangingDisappearingDelay = DEFAULT_DURATION;
    private long mChangingDelay = 0;

    /**
     * The inter-animation delays used on the changing animations
     */
    private long mChangingAppearingStagger = 0;
    private long mChangingDisappearingStagger = 0;
    private long mChangingStagger = 0;

    /**
     * Static interpolators - these are stateless and can be shared across the instances
     */
    private static TimeInterpolator ACCEL_DECEL_INTERPOLATOR =
            new AccelerateDecelerateInterpolator();
    private static TimeInterpolator DECEL_INTERPOLATOR = new DecelerateInterpolator();
    private static TimeInterpolator sAppearingInterpolator = ACCEL_DECEL_INTERPOLATOR;
    private static TimeInterpolator sDisappearingInterpolator = ACCEL_DECEL_INTERPOLATOR;
    private static TimeInterpolator sChangingAppearingInterpolator = DECEL_INTERPOLATOR;
    private static TimeInterpolator sChangingDisappearingInterpolator = DECEL_INTERPOLATOR;
    private static TimeInterpolator sChangingInterpolator = DECEL_INTERPOLATOR;

    /**
     * The default interpolators used for the animations
     */
    private TimeInterpolator mAppearingInterpolator = sAppearingInterpolator;
    private TimeInterpolator mDisappearingInterpolator = sDisappearingInterpolator;
    private TimeInterpolator mChangingAppearingInterpolator = sChangingAppearingInterpolator;
    private TimeInterpolator mChangingDisappearingInterpolator = sChangingDisappearingInterpolator;
    private TimeInterpolator mChangingInterpolator = sChangingInterpolator;

    /**
     * These hashmaps are used to store the animations that are currently running as part of
     * the transition. The reason for this is that a further layout event should cause
     * existing animations to stop where they are prior to starting new animations. So
     * we cache all of the current animations in this map for possible cancellation on
     * another layout event. LinkedHashMaps are used to preserve the order in which animations
     * are inserted, so that we process events (such as setting up start values) in the same order.
     */
    private final HashMap<View, Animator> pendingAnimations =
            new HashMap<View, Animator>();
    private final LinkedHashMap<View, Animator> currentChangingAnimations =
            new LinkedHashMap<View, Animator>();
    private final LinkedHashMap<View, Animator> currentAppearingAnimations =
            new LinkedHashMap<View, Animator>();
    private final LinkedHashMap<View, Animator> currentDisappearingAnimations =
            new LinkedHashMap<View, Animator>();

    /**
     * This hashmap is used to track the listeners that have been added to the children of
     * a container. When a layout change occurs, an animation is created for each View, so that
     * the pre-layout values can be cached in that animation. Then a listener is added to the
     * view to see whether the layout changes the bounds of that view. If so, the animation
     * is set with the final values and then run. If not, the animation is not started. When
     * the process of setting up and running all appropriate animations is done, we need to
     * remove these listeners and clear out the map.
     */
    private final HashMap<View, View.OnLayoutChangeListener> layoutChangeListenerMap =
            new HashMap<View, View.OnLayoutChangeListener>();

    /**
     * Used to track the current delay being assigned to successive animations as they are
     * started. This value is incremented for each new animation, then zeroed before the next
     * transition begins.
     */
    private long staggerDelay;

    /**
     * These are the types of transition animations that the LayoutTransition is reacting
     * to. By default, appearing/disappearing and the change animations related to them are
     * enabled (not CHANGING).
     */
    private int mTransitionTypes = FLAG_CHANGE_APPEARING | FLAG_CHANGE_DISAPPEARING |
            FLAG_APPEARING | FLAG_DISAPPEARING;
    /**
     * The set of listeners that should be notified when APPEARING/DISAPPEARING transitions
     * start and end.
     */
    private ArrayList<TransitionListener> mListeners;

    /**
     * Controls whether changing animations automatically animate the parent hierarchy as well.
     * This behavior prevents artifacts when wrap_content layouts snap to the end state as the
     * transition begins, causing visual glitches and clipping.
     * Default value is true.
     */
    private boolean mAnimateParentHierarchy = true;


    /**
     * Constructs a LayoutTransition object. By default, the object will listen to layout
     * events on any ViewGroup that it is set on and will run default animations for each
     * type of layout event.
     */
    public LayoutTransition() {
        if (defaultChangeIn == null) {
            // "left" is just a placeholder; we'll put real properties/values in when needed
            PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1);
            PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 1);
            PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", 0, 1);
            PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt("bottom", 0, 1);
            PropertyValuesHolder pvhScrollX = PropertyValuesHolder.ofInt("scrollX", 0, 1);
            PropertyValuesHolder pvhScrollY = PropertyValuesHolder.ofInt("scrollY", 0, 1);
            defaultChangeIn = ObjectAnimator.ofPropertyValuesHolder((Object)null,
                    pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScrollX, pvhScrollY);
            defaultChangeIn.setDuration(DEFAULT_DURATION);
            defaultChangeIn.setStartDelay(mChangingAppearingDelay);
            defaultChangeIn.setInterpolator(mChangingAppearingInterpolator);
            defaultChangeOut = defaultChangeIn.clone();
            defaultChangeOut.setStartDelay(mChangingDisappearingDelay);
            defaultChangeOut.setInterpolator(mChangingDisappearingInterpolator);
            defaultChange = defaultChangeIn.clone();
            defaultChange.setStartDelay(mChangingDelay);
            defaultChange.setInterpolator(mChangingInterpolator);

            defaultFadeIn = ObjectAnimator.ofFloat(null, "alpha", 0f, 1f);
            defaultFadeIn.setDuration(DEFAULT_DURATION);
            defaultFadeIn.setStartDelay(mAppearingDelay);
            defaultFadeIn.setInterpolator(mAppearingInterpolator);
            defaultFadeOut = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
            defaultFadeOut.setDuration(DEFAULT_DURATION);
            defaultFadeOut.setStartDelay(mDisappearingDelay);
            defaultFadeOut.setInterpolator(mDisappearingInterpolator);
        }
        mChangingAppearingAnim = defaultChangeIn;
        mChangingDisappearingAnim = defaultChangeOut;
        mChangingAnim = defaultChange;
        mAppearingAnim = defaultFadeIn;
        mDisappearingAnim = defaultFadeOut;
    }

    /**
     * Sets the duration to be used by all animations of this transition object. If you want to
     * set the duration of just one of the animations in particular, use the
     * {@link #setDuration(int, long)} method.
     *
     * @param duration The length of time, in milliseconds, that the transition animations
     * should last.
     */
    public void setDuration(long duration) {
        mChangingAppearingDuration = duration;
        mChangingDisappearingDuration = duration;
        mChangingDuration = duration;
        mAppearingDuration = duration;
        mDisappearingDuration = duration;
    }

    /**
     * Enables the specified transitionType for this LayoutTransition object.
     * By default, a LayoutTransition listens for changes in children being
     * added/remove/hidden/shown in the container, and runs the animations associated with
     * those events. That is, all transition types besides {@link #CHANGING} are enabled by default.
     * You can also enable {@link #CHANGING} animations by calling this method with the
     * {@link #CHANGING} transitionType.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}.
     */
    public void enableTransitionType(int transitionType) {
        switch (transitionType) {
            case APPEARING:
                mTransitionTypes |= FLAG_APPEARING;
                break;
            case DISAPPEARING:
                mTransitionTypes |= FLAG_DISAPPEARING;
                break;
            case CHANGE_APPEARING:
                mTransitionTypes |= FLAG_CHANGE_APPEARING;
                break;
            case CHANGE_DISAPPEARING:
                mTransitionTypes |= FLAG_CHANGE_DISAPPEARING;
                break;
            case CHANGING:
                mTransitionTypes |= FLAG_CHANGING;
                break;
        }
    }

    /**
     * Disables the specified transitionType for this LayoutTransition object.
     * By default, all transition types except {@link #CHANGING} are enabled.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}.
     */
    public void disableTransitionType(int transitionType) {
        switch (transitionType) {
            case APPEARING:
                mTransitionTypes &= ~FLAG_APPEARING;
                break;
            case DISAPPEARING:
                mTransitionTypes &= ~FLAG_DISAPPEARING;
                break;
            case CHANGE_APPEARING:
                mTransitionTypes &= ~FLAG_CHANGE_APPEARING;
                break;
            case CHANGE_DISAPPEARING:
                mTransitionTypes &= ~FLAG_CHANGE_DISAPPEARING;
                break;
            case CHANGING:
                mTransitionTypes &= ~FLAG_CHANGING;
                break;
        }
    }

    /**
     * Returns whether the specified transitionType is enabled for this LayoutTransition object.
     * By default, all transition types except {@link #CHANGING} are enabled.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}.
     * @return true if the specified transitionType is currently enabled, false otherwise.
     */
    public boolean isTransitionTypeEnabled(int transitionType) {
        switch (transitionType) {
            case APPEARING:
                return (mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING;
            case DISAPPEARING:
                return (mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING;
            case CHANGE_APPEARING:
                return (mTransitionTypes & FLAG_CHANGE_APPEARING) == FLAG_CHANGE_APPEARING;
            case CHANGE_DISAPPEARING:
                return (mTransitionTypes & FLAG_CHANGE_DISAPPEARING) == FLAG_CHANGE_DISAPPEARING;
            case CHANGING:
                return (mTransitionTypes & FLAG_CHANGING) == FLAG_CHANGING;
        }
        return false;
    }

    /**
     * Sets the start delay on one of the animation objects used by this transition. The
     * <code>transitionType</code> parameter determines the animation whose start delay
     * is being set.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}, which determines
     * the animation whose start delay is being set.
     * @param delay The length of time, in milliseconds, to delay before starting the animation.
     * @see Animator#setStartDelay(long)
     */
    public void setStartDelay(int transitionType, long delay) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                mChangingAppearingDelay = delay;
                break;
            case CHANGE_DISAPPEARING:
                mChangingDisappearingDelay = delay;
                break;
            case CHANGING:
                mChangingDelay = delay;
                break;
            case APPEARING:
                mAppearingDelay = delay;
                break;
            case DISAPPEARING:
                mDisappearingDelay = delay;
                break;
        }
    }

    /**
     * Gets the start delay on one of the animation objects used by this transition. The
     * <code>transitionType</code> parameter determines the animation whose start delay
     * is returned.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}, which determines
     * the animation whose start delay is returned.
     * @return long The start delay of the specified animation.
     * @see Animator#getStartDelay()
     */
    public long getStartDelay(int transitionType) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                return mChangingAppearingDelay;
            case CHANGE_DISAPPEARING:
                return mChangingDisappearingDelay;
            case CHANGING:
                return mChangingDelay;
            case APPEARING:
                return mAppearingDelay;
            case DISAPPEARING:
                return mDisappearingDelay;
        }
        // shouldn't reach here
        return 0;
    }

    /**
     * Sets the duration on one of the animation objects used by this transition. The
     * <code>transitionType</code> parameter determines the animation whose duration
     * is being set.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}, which determines
     * the animation whose duration is being set.
     * @param duration The length of time, in milliseconds, that the specified animation should run.
     * @see Animator#setDuration(long)
     */
    public void setDuration(int transitionType, long duration) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                mChangingAppearingDuration = duration;
                break;
            case CHANGE_DISAPPEARING:
                mChangingDisappearingDuration = duration;
                break;
            case CHANGING:
                mChangingDuration = duration;
                break;
            case APPEARING:
                mAppearingDuration = duration;
                break;
            case DISAPPEARING:
                mDisappearingDuration = duration;
                break;
        }
    }

    /**
     * Gets the duration on one of the animation objects used by this transition. The
     * <code>transitionType</code> parameter determines the animation whose duration
     * is returned.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}, which determines
     * the animation whose duration is returned.
     * @return long The duration of the specified animation.
     * @see Animator#getDuration()
     */
    public long getDuration(int transitionType) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                return mChangingAppearingDuration;
            case CHANGE_DISAPPEARING:
                return mChangingDisappearingDuration;
            case CHANGING:
                return mChangingDuration;
            case APPEARING:
                return mAppearingDuration;
            case DISAPPEARING:
                return mDisappearingDuration;
        }
        // shouldn't reach here
        return 0;
    }

    /**
     * Sets the length of time to delay between starting each animation during one of the
     * change animations.
     *
     * @param transitionType A value of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING}, or
     * {@link #CHANGING}.
     * @param duration The length of time, in milliseconds, to delay before launching the next
     * animation in the sequence.
     */
    public void setStagger(int transitionType, long duration) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                mChangingAppearingStagger = duration;
                break;
            case CHANGE_DISAPPEARING:
                mChangingDisappearingStagger = duration;
                break;
            case CHANGING:
                mChangingStagger = duration;
                break;
            // noop other cases
        }
    }

    /**
     * Gets the length of time to delay between starting each animation during one of the
     * change animations.
     *
     * @param transitionType A value of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING}, or
     * {@link #CHANGING}.
     * @return long The length of time, in milliseconds, to delay before launching the next
     * animation in the sequence.
     */
    public long getStagger(int transitionType) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                return mChangingAppearingStagger;
            case CHANGE_DISAPPEARING:
                return mChangingDisappearingStagger;
            case CHANGING:
                return mChangingStagger;
        }
        // shouldn't reach here
        return 0;
    }

    /**
     * Sets the interpolator on one of the animation objects used by this transition. The
     * <code>transitionType</code> parameter determines the animation whose interpolator
     * is being set.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}, which determines
     * the animation whose interpolator is being set.
     * @param interpolator The interpolator that the specified animation should use.
     * @see Animator#setInterpolator(TimeInterpolator)
     */
    public void setInterpolator(int transitionType, TimeInterpolator interpolator) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                mChangingAppearingInterpolator = interpolator;
                break;
            case CHANGE_DISAPPEARING:
                mChangingDisappearingInterpolator = interpolator;
                break;
            case CHANGING:
                mChangingInterpolator = interpolator;
                break;
            case APPEARING:
                mAppearingInterpolator = interpolator;
                break;
            case DISAPPEARING:
                mDisappearingInterpolator = interpolator;
                break;
        }
    }

    /**
     * Gets the interpolator on one of the animation objects used by this transition. The
     * <code>transitionType</code> parameter determines the animation whose interpolator
     * is returned.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}, which determines
     * the animation whose interpolator is being returned.
     * @return TimeInterpolator The interpolator that the specified animation uses.
     * @see Animator#setInterpolator(TimeInterpolator)
     */
    public TimeInterpolator getInterpolator(int transitionType) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                return mChangingAppearingInterpolator;
            case CHANGE_DISAPPEARING:
                return mChangingDisappearingInterpolator;
            case CHANGING:
                return mChangingInterpolator;
            case APPEARING:
                return mAppearingInterpolator;
            case DISAPPEARING:
                return mDisappearingInterpolator;
        }
        // shouldn't reach here
        return null;
    }

    /**
     * Sets the animation used during one of the transition types that may run. Any
     * Animator object can be used, but to be most useful in the context of layout
     * transitions, the animation should either be a ObjectAnimator or a AnimatorSet
     * of animations including PropertyAnimators. Also, these ObjectAnimator objects
     * should be able to get and set values on their target objects automatically. For
     * example, a ObjectAnimator that animates the property "left" is able to set and get the
     * <code>left</code> property from the View objects being animated by the layout
     * transition. The transition works by setting target objects and properties
     * dynamically, according to the pre- and post-layoout values of those objects, so
     * having animations that can handle those properties appropriately will work best
     * for custom animation. The dynamic setting of values is only the case for the
     * CHANGE animations; the APPEARING and DISAPPEARING animations are simply run with
     * the values they have.
     *
     * <p>It is also worth noting that any and all animations (and their underlying
     * PropertyValuesHolder objects) will have their start and end values set according
     * to the pre- and post-layout values. So, for example, a custom animation on "alpha"
     * as the CHANGE_APPEARING animation will inherit the real value of alpha on the target
     * object (presumably 1) as its starting and ending value when the animation begins.
     * Animations which need to use values at the beginning and end that may not match the
     * values queried when the transition begins may need to use a different mechanism
     * than a standard ObjectAnimator object.</p>
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}, which determines the
     * animation whose animator is being set.
     * @param animator The animation being assigned. A value of <code>null</code> means that no
     * animation will be run for the specified transitionType.
     */
    public void setAnimator(int transitionType, Animator animator) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                mChangingAppearingAnim = animator;
                break;
            case CHANGE_DISAPPEARING:
                mChangingDisappearingAnim = animator;
                break;
            case CHANGING:
                mChangingAnim = animator;
                break;
            case APPEARING:
                mAppearingAnim = animator;
                break;
            case DISAPPEARING:
                mDisappearingAnim = animator;
                break;
        }
    }

    /**
     * Gets the animation used during one of the transition types that may run.
     *
     * @param transitionType One of {@link #CHANGE_APPEARING}, {@link #CHANGE_DISAPPEARING},
     * {@link #CHANGING}, {@link #APPEARING}, or {@link #DISAPPEARING}, which determines
     * the animation whose animator is being returned.
     * @return Animator The animation being used for the given transition type.
     * @see #setAnimator(int, Animator)
     */
    public Animator getAnimator(int transitionType) {
        switch (transitionType) {
            case CHANGE_APPEARING:
                return mChangingAppearingAnim;
            case CHANGE_DISAPPEARING:
                return mChangingDisappearingAnim;
            case CHANGING:
                return mChangingAnim;
            case APPEARING:
                return mAppearingAnim;
            case DISAPPEARING:
                return mDisappearingAnim;
        }
        // shouldn't reach here
        return null;
    }

    /**
     * This function sets up animations on all of the views that change during layout.
     * For every child in the parent, we create a change animation of the appropriate
     * type (appearing, disappearing, or changing) and ask it to populate its start values from its
     * target view. We add layout listeners to all child views and listen for changes. For
     * those views that change, we populate the end values for those animations and start them.
     * Animations are not run on unchanging views.
     *
     * @param parent The container which is undergoing a change.
     * @param newView The view being added to or removed from the parent. May be null if the
     * changeReason is CHANGING.
     * @param changeReason A value of APPEARING, DISAPPEARING, or CHANGING, indicating whether the
     * transition is occurring because an item is being added to or removed from the parent, or
     * if it is running in response to a layout operation (that is, if the value is CHANGING).
     */
    private void runChangeTransition(final ViewGroup parent, View newView, final int changeReason) {

        Animator baseAnimator = null;
        Animator parentAnimator = null;
        final long duration;
        switch (changeReason) {
            case APPEARING:
                baseAnimator = mChangingAppearingAnim;
                duration = mChangingAppearingDuration;
                parentAnimator = defaultChangeIn;
                break;
            case DISAPPEARING:
                baseAnimator = mChangingDisappearingAnim;
                duration = mChangingDisappearingDuration;
                parentAnimator = defaultChangeOut;
                break;
            case CHANGING:
                baseAnimator = mChangingAnim;
                duration = mChangingDuration;
                parentAnimator = defaultChange;
                break;
            default:
                // Shouldn't reach here
                duration = 0;
                break;
        }
        // If the animation is null, there's nothing to do
        if (baseAnimator == null) {
            return;
        }

        // reset the inter-animation delay, in case we use it later
        staggerDelay = 0;

        final ViewTreeObserver observer = parent.getViewTreeObserver();
        if (!observer.isAlive()) {
            // If the observer's not in a good state, skip the transition
            return;
        }
        int numChildren = parent.getChildCount();

        for (int i = 0; i < numChildren; ++i) {
            final View child = parent.getChildAt(i);

            // only animate the views not being added or removed
            if (child != newView) {
                setupChangeAnimation(parent, changeReason, baseAnimator, duration, child);
            }
        }
        if (mAnimateParentHierarchy) {
            ViewGroup tempParent = parent;
            while (tempParent != null) {
                ViewParent parentParent = tempParent.getParent();
                if (parentParent instanceof ViewGroup) {
                    setupChangeAnimation((ViewGroup)parentParent, changeReason, parentAnimator,
                            duration, tempParent);
                    tempParent = (ViewGroup) parentParent;
                } else {
                    tempParent = null;
                }

            }
        }

        // This is the cleanup step. When we get this rendering event, we know that all of
        // the appropriate animations have been set up and run. Now we can clear out the
        // layout listeners.
        CleanupCallback callback = new CleanupCallback(layoutChangeListenerMap, parent);
        observer.addOnPreDrawListener(callback);
        parent.addOnAttachStateChangeListener(callback);
    }

    /**
     * This flag controls whether CHANGE_APPEARING or CHANGE_DISAPPEARING animations will
     * cause the default changing animation to be run on the parent hierarchy as well. This allows
     * containers of transitioning views to also transition, which may be necessary in situations
     * where the containers bounds change between the before/after states and may clip their
     * children during the transition animations. For example, layouts with wrap_content will
     * adjust their bounds according to the dimensions of their children.
     *
     * <p>The default changing transitions animate the bounds and scroll positions of the
     * target views. These are the animations that will run on the parent hierarchy, not
     * the custom animations that happen to be set on the transition. This allows custom
     * behavior for the children of the transitioning container, but uses standard behavior
     * of resizing/rescrolling on any changing parents.
     *
     * @param animateParentHierarchy A boolean value indicating whether the parents of
     * transitioning views should also be animated during the transition. Default value is true.
     */
    public void setAnimateParentHierarchy(boolean animateParentHierarchy) {
        mAnimateParentHierarchy = animateParentHierarchy;
    }

    /**
     * Utility function called by runChangingTransition for both the children and the parent
     * hierarchy.
     */
    private void setupChangeAnimation(final ViewGroup parent, final int changeReason,
            Animator baseAnimator, final long duration, final View child) {

        // If we already have a listener for this child, then we've already set up the
        // changing animation we need. Multiple calls for a child may occur when several
        // add/remove operations are run at once on a container; each one will trigger
        // changes for the existing children in the container.
        if (layoutChangeListenerMap.get(child) != null) {
            return;
        }

        // Don't animate items up from size(0,0); this is likely because the objects
        // were offscreen/invisible or otherwise measured to be infinitely small. We don't
        // want to see them animate into their real size; just ignore animation requests
        // on these views
        if (child.getWidth() == 0 && child.getHeight() == 0) {
            return;
        }

        // Make a copy of the appropriate animation
        final Animator anim = baseAnimator.clone();

        // Set the target object for the animation
        anim.setTarget(child);

        // A ObjectAnimator (or AnimatorSet of them) can extract start values from
        // its target object
        anim.setupStartValues();

        // If there's an animation running on this view already, cancel it
        Animator currentAnimation = pendingAnimations.get(child);
        if (currentAnimation != null) {
            currentAnimation.cancel();
            pendingAnimations.remove(child);
        }
        // Cache the animation in case we need to cancel it later
        pendingAnimations.put(child, anim);

        // For the animations which don't get started, we have to have a means of
        // removing them from the cache, lest we leak them and their target objects.
        // We run an animator for the default duration+100 (an arbitrary time, but one
        // which should far surpass the delay between setting them up here and
        // handling layout events which start them.
        ValueAnimator pendingAnimRemover = ValueAnimator.ofFloat(0f, 1f).
                setDuration(duration + 100);
        pendingAnimRemover.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                pendingAnimations.remove(child);
            }
        });
        pendingAnimRemover.start();

        // Add a listener to track layout changes on this view. If we don't get a callback,
        // then there's nothing to animate.
        final View.OnLayoutChangeListener listener = new View.OnLayoutChangeListener() {
            public void onLayoutChange(View v, int left, int top, int right, int bottom,
                    int oldLeft, int oldTop, int oldRight, int oldBottom) {

                // Tell the animation to extract end values from the changed object
                anim.setupEndValues();
                if (anim instanceof ValueAnimator) {
                    boolean valuesDiffer = false;
                    ValueAnimator valueAnim = (ValueAnimator)anim;
                    PropertyValuesHolder[] oldValues = valueAnim.getValues();
                    for (int i = 0; i < oldValues.length; ++i) {
                        PropertyValuesHolder pvh = oldValues[i];
                        if (pvh.mKeyframes instanceof KeyframeSet) {
                            KeyframeSet keyframeSet = (KeyframeSet) pvh.mKeyframes;
                            if (keyframeSet.mFirstKeyframe == null ||
                                    keyframeSet.mLastKeyframe == null ||
                                    !keyframeSet.mFirstKeyframe.getValue().equals(
                                            keyframeSet.mLastKeyframe.getValue())) {
                                valuesDiffer = true;
                            }
                        } else if (!pvh.mKeyframes.getValue(0).equals(pvh.mKeyframes.getValue(1))) {
                            valuesDiffer = true;
                        }
                    }
                    if (!valuesDiffer) {
                        return;
                    }
                }

                long startDelay = 0;
                switch (changeReason) {
                    case APPEARING:
                        startDelay = mChangingAppearingDelay + staggerDelay;
                        staggerDelay += mChangingAppearingStagger;
                        if (mChangingAppearingInterpolator != sChangingAppearingInterpolator) {
                            anim.setInterpolator(mChangingAppearingInterpolator);
                        }
                        break;
                    case DISAPPEARING:
                        startDelay = mChangingDisappearingDelay + staggerDelay;
                        staggerDelay += mChangingDisappearingStagger;
                        if (mChangingDisappearingInterpolator !=
                                sChangingDisappearingInterpolator) {
                            anim.setInterpolator(mChangingDisappearingInterpolator);
                        }
                        break;
                    case CHANGING:
                        startDelay = mChangingDelay + staggerDelay;
                        staggerDelay += mChangingStagger;
                        if (mChangingInterpolator != sChangingInterpolator) {
                            anim.setInterpolator(mChangingInterpolator);
                        }
                        break;
                }
                anim.setStartDelay(startDelay);
                anim.setDuration(duration);

                Animator prevAnimation = currentChangingAnimations.get(child);
                if (prevAnimation != null) {
                    prevAnimation.cancel();
                }
                Animator pendingAnimation = pendingAnimations.get(child);
                if (pendingAnimation != null) {
                    pendingAnimations.remove(child);
                }
                // Cache the animation in case we need to cancel it later
                currentChangingAnimations.put(child, anim);

                parent.requestTransitionStart(LayoutTransition.this);

                // this only removes listeners whose views changed - must clear the
                // other listeners later
                child.removeOnLayoutChangeListener(this);
                layoutChangeListenerMap.remove(child);
            }
        };
        // Remove the animation from the cache when it ends
        anim.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationStart(Animator animator) {
                if (hasListeners()) {
                    ArrayList<TransitionListener> listeners =
                            (ArrayList<TransitionListener>) mListeners.clone();
                    for (TransitionListener listener : listeners) {
                        listener.startTransition(LayoutTransition.this, parent, child,
                                changeReason == APPEARING ?
                                        CHANGE_APPEARING : changeReason == DISAPPEARING ?
                                        CHANGE_DISAPPEARING : CHANGING);
                    }
                }
            }

            @Override
            public void onAnimationCancel(Animator animator) {
                child.removeOnLayoutChangeListener(listener);
                layoutChangeListenerMap.remove(child);
            }

            @Override
            public void onAnimationEnd(Animator animator) {
                currentChangingAnimations.remove(child);
                if (hasListeners()) {
                    ArrayList<TransitionListener> listeners =
                            (ArrayList<TransitionListener>) mListeners.clone();
                    for (TransitionListener listener : listeners) {
                        listener.endTransition(LayoutTransition.this, parent, child,
                                changeReason == APPEARING ?
                                        CHANGE_APPEARING : changeReason == DISAPPEARING ?
                                        CHANGE_DISAPPEARING : CHANGING);
                    }
                }
            }
        });

        child.addOnLayoutChangeListener(listener);
        // cache the listener for later removal
        layoutChangeListenerMap.put(child, listener);
    }

    /**
     * Starts the animations set up for a CHANGING transition. We separate the setup of these
     * animations from actually starting them, to avoid side-effects that starting the animations
     * may have on the properties of the affected objects. After setup, we tell the affected parent
     * that this transition should be started. The parent informs its ViewAncestor, which then
     * starts the transition after the current layout/measurement phase, just prior to drawing
     * the view hierarchy.
     *
     * @hide
     */
    public void startChangingAnimations() {
        LinkedHashMap<View, Animator> currentAnimCopy =
                (LinkedHashMap<View, Animator>) currentChangingAnimations.clone();
        for (Animator anim : currentAnimCopy.values()) {
            if (anim instanceof ObjectAnimator) {
                ((ObjectAnimator) anim).setCurrentPlayTime(0);
            }
            anim.start();
        }
    }

    /**
     * Ends the animations that are set up for a CHANGING transition. This is a variant of
     * startChangingAnimations() which is called when the window the transition is playing in
     * is not visible. We need to make sure the animations put their targets in their end states
     * and that the transition finishes to remove any mid-process state (such as isRunning()).
     *
     * @hide
     */
    public void endChangingAnimations() {
        LinkedHashMap<View, Animator> currentAnimCopy =
                (LinkedHashMap<View, Animator>) currentChangingAnimations.clone();
        for (Animator anim : currentAnimCopy.values()) {
            anim.start();
            anim.end();
        }
        // listeners should clean up the currentChangingAnimations list, but just in case...
        currentChangingAnimations.clear();
    }

    /**
     * Returns true if animations are running which animate layout-related properties. This
     * essentially means that either CHANGE_APPEARING or CHANGE_DISAPPEARING animations
     * are running, since these animations operate on layout-related properties.
     *
     * @return true if CHANGE_APPEARING or CHANGE_DISAPPEARING animations are currently
     * running.
     */
    public boolean isChangingLayout() {
        return (currentChangingAnimations.size() > 0);
    }

    /**
     * Returns true if any of the animations in this transition are currently running.
     *
     * @return true if any animations in the transition are running.
     */
    public boolean isRunning() {
        return (currentChangingAnimations.size() > 0 || currentAppearingAnimations.size() > 0 ||
                currentDisappearingAnimations.size() > 0);
    }

    /**
     * Cancels the currently running transition. Note that we cancel() the changing animations
     * but end() the visibility animations. This is because this method is currently called
     * in the context of starting a new transition, so we want to move things from their mid-
     * transition positions, but we want them to have their end-transition visibility.
     *
     * @hide
     */
    public void cancel() {
        if (currentChangingAnimations.size() > 0) {
            LinkedHashMap<View, Animator> currentAnimCopy =
                    (LinkedHashMap<View, Animator>) currentChangingAnimations.clone();
            for (Animator anim : currentAnimCopy.values()) {
                anim.cancel();
            }
            currentChangingAnimations.clear();
        }
        if (currentAppearingAnimations.size() > 0) {
            LinkedHashMap<View, Animator> currentAnimCopy =
                    (LinkedHashMap<View, Animator>) currentAppearingAnimations.clone();
            for (Animator anim : currentAnimCopy.values()) {
                anim.end();
            }
            currentAppearingAnimations.clear();
        }
        if (currentDisappearingAnimations.size() > 0) {
            LinkedHashMap<View, Animator> currentAnimCopy =
                    (LinkedHashMap<View, Animator>) currentDisappearingAnimations.clone();
            for (Animator anim : currentAnimCopy.values()) {
                anim.end();
            }
            currentDisappearingAnimations.clear();
        }
    }

    /**
     * Cancels the specified type of transition. Note that we cancel() the changing animations
     * but end() the visibility animations. This is because this method is currently called
     * in the context of starting a new transition, so we want to move things from their mid-
     * transition positions, but we want them to have their end-transition visibility.
     *
     * @hide
     */
    public void cancel(int transitionType) {
        switch (transitionType) {
            case CHANGE_APPEARING:
            case CHANGE_DISAPPEARING:
            case CHANGING:
                if (currentChangingAnimations.size() > 0) {
                    LinkedHashMap<View, Animator> currentAnimCopy =
                            (LinkedHashMap<View, Animator>) currentChangingAnimations.clone();
                    for (Animator anim : currentAnimCopy.values()) {
                        anim.cancel();
                    }
                    currentChangingAnimations.clear();
                }
                break;
            case APPEARING:
                if (currentAppearingAnimations.size() > 0) {
                    LinkedHashMap<View, Animator> currentAnimCopy =
                            (LinkedHashMap<View, Animator>) currentAppearingAnimations.clone();
                    for (Animator anim : currentAnimCopy.values()) {
                        anim.end();
                    }
                    currentAppearingAnimations.clear();
                }
                break;
            case DISAPPEARING:
                if (currentDisappearingAnimations.size() > 0) {
                    LinkedHashMap<View, Animator> currentAnimCopy =
                            (LinkedHashMap<View, Animator>) currentDisappearingAnimations.clone();
                    for (Animator anim : currentAnimCopy.values()) {
                        anim.end();
                    }
                    currentDisappearingAnimations.clear();
                }
                break;
        }
    }

    /**
     * This method runs the animation that makes an added item appear.
     *
     * @param parent The ViewGroup to which the View is being added.
     * @param child The View being added to the ViewGroup.
     */
    private void runAppearingTransition(final ViewGroup parent, final View child) {
        Animator currentAnimation = currentDisappearingAnimations.get(child);
        if (currentAnimation != null) {
            currentAnimation.cancel();
        }
        if (mAppearingAnim == null) {
            if (hasListeners()) {
                ArrayList<TransitionListener> listeners =
                        (ArrayList<TransitionListener>) mListeners.clone();
                for (TransitionListener listener : listeners) {
                    listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
                }
            }
            return;
        }
        Animator anim = mAppearingAnim.clone();
        anim.setTarget(child);
        anim.setStartDelay(mAppearingDelay);
        anim.setDuration(mAppearingDuration);
        if (mAppearingInterpolator != sAppearingInterpolator) {
            anim.setInterpolator(mAppearingInterpolator);
        }
        if (anim instanceof ObjectAnimator) {
            ((ObjectAnimator) anim).setCurrentPlayTime(0);
        }
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator anim) {
                currentAppearingAnimations.remove(child);
                if (hasListeners()) {
                    ArrayList<TransitionListener> listeners =
                            (ArrayList<TransitionListener>) mListeners.clone();
                    for (TransitionListener listener : listeners) {
                        listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
                    }
                }
            }
        });
        currentAppearingAnimations.put(child, anim);
        anim.start();
    }

    /**
     * This method runs the animation that makes a removed item disappear.
     *
     * @param parent The ViewGroup from which the View is being removed.
     * @param child The View being removed from the ViewGroup.
     */
    private void runDisappearingTransition(final ViewGroup parent, final View child) {
        Animator currentAnimation = currentAppearingAnimations.get(child);
        if (currentAnimation != null) {
            currentAnimation.cancel();
        }
        if (mDisappearingAnim == null) {
            if (hasListeners()) {
                ArrayList<TransitionListener> listeners =
                        (ArrayList<TransitionListener>) mListeners.clone();
                for (TransitionListener listener : listeners) {
                    listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
                }
            }
            return;
        }
        Animator anim = mDisappearingAnim.clone();
        anim.setStartDelay(mDisappearingDelay);
        anim.setDuration(mDisappearingDuration);
        if (mDisappearingInterpolator != sDisappearingInterpolator) {
            anim.setInterpolator(mDisappearingInterpolator);
        }
        anim.setTarget(child);
        final float preAnimAlpha = child.getAlpha();
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator anim) {
                currentDisappearingAnimations.remove(child);
                child.setAlpha(preAnimAlpha);
                if (hasListeners()) {
                    ArrayList<TransitionListener> listeners =
                            (ArrayList<TransitionListener>) mListeners.clone();
                    for (TransitionListener listener : listeners) {
                        listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
                    }
                }
            }
        });
        if (anim instanceof ObjectAnimator) {
            ((ObjectAnimator) anim).setCurrentPlayTime(0);
        }
        currentDisappearingAnimations.put(child, anim);
        anim.start();
    }

    /**
     * This method is called by ViewGroup when a child view is about to be added to the
     * container. This callback starts the process of a transition; we grab the starting
     * values, listen for changes to all of the children of the container, and start appropriate
     * animations.
     *
     * @param parent The ViewGroup to which the View is being added.
     * @param child The View being added to the ViewGroup.
     * @param changesLayout Whether the removal will cause changes in the layout of other views
     * in the container. INVISIBLE views becoming VISIBLE will not cause changes and thus will not
     * affect CHANGE_APPEARING or CHANGE_DISAPPEARING animations.
     */
    private void addChild(ViewGroup parent, View child, boolean changesLayout) {
        if (parent.getWindowVisibility() != View.VISIBLE) {
            return;
        }
        if ((mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING) {
            // Want disappearing animations to finish up before proceeding
            cancel(DISAPPEARING);
        }
        if (changesLayout && (mTransitionTypes & FLAG_CHANGE_APPEARING) == FLAG_CHANGE_APPEARING) {
            // Also, cancel changing animations so that we start fresh ones from current locations
            cancel(CHANGE_APPEARING);
            cancel(CHANGING);
        }
        if (hasListeners() && (mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING) {
            ArrayList<TransitionListener> listeners =
                    (ArrayList<TransitionListener>) mListeners.clone();
            for (TransitionListener listener : listeners) {
                listener.startTransition(this, parent, child, APPEARING);
            }
        }
        if (changesLayout && (mTransitionTypes & FLAG_CHANGE_APPEARING) == FLAG_CHANGE_APPEARING) {
            runChangeTransition(parent, child, APPEARING);
        }
        if ((mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING) {
            runAppearingTransition(parent, child);
        }
    }

    private boolean hasListeners() {
        return mListeners != null && mListeners.size() > 0;
    }

    /**
     * This method is called by ViewGroup when there is a call to layout() on the container
     * with this LayoutTransition. If the CHANGING transition is enabled and if there is no other
     * transition currently running on the container, then this call runs a CHANGING transition.
     * The transition does not start immediately; it just sets up the mechanism to run if any
     * of the children of the container change their layout parameters (similar to
     * the CHANGE_APPEARING and CHANGE_DISAPPEARING transitions).
     *
     * @param parent The ViewGroup whose layout() method has been called.
     *
     * @hide
     */
    public void layoutChange(ViewGroup parent) {
        if (parent.getWindowVisibility() != View.VISIBLE) {
            return;
        }
        if ((mTransitionTypes & FLAG_CHANGING) == FLAG_CHANGING  && !isRunning()) {
            // This method is called for all calls to layout() in the container, including
            // those caused by add/remove/hide/show events, which will already have set up
            // transition animations. Avoid setting up CHANGING animations in this case; only
            // do so when there is not a transition already running on the container.
            runChangeTransition(parent, null, CHANGING);
        }
    }

    /**
     * This method is called by ViewGroup when a child view is about to be added to the
     * container. This callback starts the process of a transition; we grab the starting
     * values, listen for changes to all of the children of the container, and start appropriate
     * animations.
     *
     * @param parent The ViewGroup to which the View is being added.
     * @param child The View being added to the ViewGroup.
     */
    public void addChild(ViewGroup parent, View child) {
        addChild(parent, child, true);
    }

    /**
     * @deprecated Use {@link #showChild(android.view.ViewGroup, android.view.View, int)}.
     */
    @Deprecated
    public void showChild(ViewGroup parent, View child) {
        addChild(parent, child, true);
    }

    /**
     * This method is called by ViewGroup when a child view is about to be made visible in the
     * container. This callback starts the process of a transition; we grab the starting
     * values, listen for changes to all of the children of the container, and start appropriate
     * animations.
     *
     * @param parent The ViewGroup in which the View is being made visible.
     * @param child The View being made visible.
     * @param oldVisibility The previous visibility value of the child View, either
     * {@link View#GONE} or {@link View#INVISIBLE}.
     */
    public void showChild(ViewGroup parent, View child, int oldVisibility) {
        addChild(parent, child, oldVisibility == View.GONE);
    }

    /**
     * This method is called by ViewGroup when a child view is about to be removed from the
     * container. This callback starts the process of a transition; we grab the starting
     * values, listen for changes to all of the children of the container, and start appropriate
     * animations.
     *
     * @param parent The ViewGroup from which the View is being removed.
     * @param child The View being removed from the ViewGroup.
     * @param changesLayout Whether the removal will cause changes in the layout of other views
     * in the container. Views becoming INVISIBLE will not cause changes and thus will not
     * affect CHANGE_APPEARING or CHANGE_DISAPPEARING animations.
     */
    private void removeChild(ViewGroup parent, View child, boolean changesLayout) {
        if (parent.getWindowVisibility() != View.VISIBLE) {
            return;
        }
        if ((mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) {
            // Want appearing animations to finish up before proceeding
            cancel(APPEARING);
        }
        if (changesLayout &&
                (mTransitionTypes & FLAG_CHANGE_DISAPPEARING) == FLAG_CHANGE_DISAPPEARING) {
            // Also, cancel changing animations so that we start fresh ones from current locations
            cancel(CHANGE_DISAPPEARING);
            cancel(CHANGING);
        }
        if (hasListeners() && (mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) {
            ArrayList<TransitionListener> listeners = (ArrayList<TransitionListener>) mListeners
                    .clone();
            for (TransitionListener listener : listeners) {
                listener.startTransition(this, parent, child, DISAPPEARING);
            }
        }
        if (changesLayout &&
                (mTransitionTypes & FLAG_CHANGE_DISAPPEARING) == FLAG_CHANGE_DISAPPEARING) {
            runChangeTransition(parent, child, DISAPPEARING);
        }
        if ((mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) {
            runDisappearingTransition(parent, child);
        }
    }

    /**
     * This method is called by ViewGroup when a child view is about to be removed from the
     * container. This callback starts the process of a transition; we grab the starting
     * values, listen for changes to all of the children of the container, and start appropriate
     * animations.
     *
     * @param parent The ViewGroup from which the View is being removed.
     * @param child The View being removed from the ViewGroup.
     */
    public void removeChild(ViewGroup parent, View child) {
        removeChild(parent, child, true);
    }

    /**
     * @deprecated Use {@link #hideChild(android.view.ViewGroup, android.view.View, int)}.
     */
    @Deprecated
    public void hideChild(ViewGroup parent, View child) {
        removeChild(parent, child, true);
    }

    /**
     * This method is called by ViewGroup when a child view is about to be hidden in
     * container. This callback starts the process of a transition; we grab the starting
     * values, listen for changes to all of the children of the container, and start appropriate
     * animations.
     *
     * @param parent The parent ViewGroup of the View being hidden.
     * @param child The View being hidden.
     * @param newVisibility The new visibility value of the child View, either
     * {@link View#GONE} or {@link View#INVISIBLE}.
     */
    public void hideChild(ViewGroup parent, View child, int newVisibility) {
        removeChild(parent, child, newVisibility == View.GONE);
    }

    /**
     * Add a listener that will be called when the bounds of the view change due to
     * layout processing.
     *
     * @param listener The listener that will be called when layout bounds change.
     */
    public void addTransitionListener(TransitionListener listener) {
        if (mListeners == null) {
            mListeners = new ArrayList<TransitionListener>();
        }
        mListeners.add(listener);
    }

    /**
     * Remove a listener for layout changes.
     *
     * @param listener The listener for layout bounds change.
     */
    public void removeTransitionListener(TransitionListener listener) {
        if (mListeners == null) {
            return;
        }
        mListeners.remove(listener);
    }

    /**
     * Gets the current list of listeners for layout changes.
     * @return
     */
    public List<TransitionListener> getTransitionListeners() {
        return mListeners;
    }

    /**
     * This interface is used for listening to starting and ending events for transitions.
     */
    public interface TransitionListener {

        /**
         * This event is sent to listeners when any type of transition animation begins.
         *
         * @param transition The LayoutTransition sending out the event.
         * @param container The ViewGroup on which the transition is playing.
         * @param view The View object being affected by the transition animation.
         * @param transitionType The type of transition that is beginning,
         * {@link android.animation.LayoutTransition#APPEARING},
         * {@link android.animation.LayoutTransition#DISAPPEARING},
         * {@link android.animation.LayoutTransition#CHANGE_APPEARING}, or
         * {@link android.animation.LayoutTransition#CHANGE_DISAPPEARING}.
         */
        public void startTransition(LayoutTransition transition, ViewGroup container,
                View view, int transitionType);

        /**
         * This event is sent to listeners when any type of transition animation ends.
         *
         * @param transition The LayoutTransition sending out the event.
         * @param container The ViewGroup on which the transition is playing.
         * @param view The View object being affected by the transition animation.
         * @param transitionType The type of transition that is ending,
         * {@link android.animation.LayoutTransition#APPEARING},
         * {@link android.animation.LayoutTransition#DISAPPEARING},
         * {@link android.animation.LayoutTransition#CHANGE_APPEARING}, or
         * {@link android.animation.LayoutTransition#CHANGE_DISAPPEARING}.
         */
        public void endTransition(LayoutTransition transition, ViewGroup container,
                View view, int transitionType);
    }

    /**
     * Utility class to clean up listeners after animations are setup. Cleanup happens
     * when either the OnPreDrawListener method is called or when the parent is detached,
     * whichever comes first.
     */
    private static final class CleanupCallback implements ViewTreeObserver.OnPreDrawListener,
            View.OnAttachStateChangeListener {

        final Map<View, View.OnLayoutChangeListener> layoutChangeListenerMap;
        final ViewGroup parent;

        CleanupCallback(Map<View, View.OnLayoutChangeListener> listenerMap, ViewGroup parent) {
            this.layoutChangeListenerMap = listenerMap;
            this.parent = parent;
        }

        private void cleanup() {
            parent.getViewTreeObserver().removeOnPreDrawListener(this);
            parent.removeOnAttachStateChangeListener(this);
            int count = layoutChangeListenerMap.size();
            if (count > 0) {
                Collection<View> views = layoutChangeListenerMap.keySet();
                for (View view : views) {
                    View.OnLayoutChangeListener listener = layoutChangeListenerMap.get(view);
                    view.removeOnLayoutChangeListener(listener);
                }
                layoutChangeListenerMap.clear();
            }
        }

        @Override
        public void onViewAttachedToWindow(View v) {
        }

        @Override
        public void onViewDetachedFromWindow(View v) {
            cleanup();
        }

        @Override
        public boolean onPreDraw() {
            cleanup();
            return true;
        }
    };

}
