Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 13351997 authored by Doris Liu's avatar Doris Liu
Browse files

New functionalities for AnimatorSet: Reverse, Seek

This CL adds reverse and seek to AnimatorSet's capabilities.

Structural changes:
1) Child animators are now being pulsed by AnimatorSet in a more
   timeline manner, as opposed to the old listener based style.
   This timeline based approach avoids the time offset in between
   sequential animations, and therefore produces a more accurate
   overall duration.
2) Timeline is done by representing start and end of each child animator
   in two separate events. All the events are then sorted based on the
   time they happen, such that it's clear what should happen in between
   last frame and the new frame (i.e. which animations should start
   or end).

Test: CTS (in the same topic branch)
Bug: 30993532

Change-Id: If1dc6e8dbc93a4bf5ade8c5b0dcf43d3ee6ba7b5
parent b81d9784
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3067,8 +3067,10 @@ package android.animation {
  public static abstract interface Animator.AnimatorListener {
    method public abstract void onAnimationCancel(android.animation.Animator);
    method public default void onAnimationEnd(android.animation.Animator, boolean);
    method public abstract void onAnimationEnd(android.animation.Animator);
    method public abstract void onAnimationRepeat(android.animation.Animator);
    method public default void onAnimationStart(android.animation.Animator, boolean);
    method public abstract void onAnimationStart(android.animation.Animator);
  }
@@ -3104,6 +3106,8 @@ package android.animation {
    method public void playSequentially(java.util.List<android.animation.Animator>);
    method public void playTogether(android.animation.Animator...);
    method public void playTogether(java.util.Collection<android.animation.Animator>);
    method public void reverse();
    method public void setCurrentPlayTime(long);
    method public android.animation.AnimatorSet setDuration(long);
    method public void setInterpolator(android.animation.TimeInterpolator);
    method public void setStartDelay(long);
+4 −0
Original line number Diff line number Diff line
@@ -3186,8 +3186,10 @@ package android.animation {
  public static abstract interface Animator.AnimatorListener {
    method public abstract void onAnimationCancel(android.animation.Animator);
    method public default void onAnimationEnd(android.animation.Animator, boolean);
    method public abstract void onAnimationEnd(android.animation.Animator);
    method public abstract void onAnimationRepeat(android.animation.Animator);
    method public default void onAnimationStart(android.animation.Animator, boolean);
    method public abstract void onAnimationStart(android.animation.Animator);
  }
@@ -3223,6 +3225,8 @@ package android.animation {
    method public void playSequentially(java.util.List<android.animation.Animator>);
    method public void playTogether(android.animation.Animator...);
    method public void playTogether(java.util.Collection<android.animation.Animator>);
    method public void reverse();
    method public void setCurrentPlayTime(long);
    method public android.animation.AnimatorSet setDuration(long);
    method public void setInterpolator(android.animation.TimeInterpolator);
    method public void setStartDelay(long);
+4 −0
Original line number Diff line number Diff line
@@ -3067,8 +3067,10 @@ package android.animation {
  public static abstract interface Animator.AnimatorListener {
    method public abstract void onAnimationCancel(android.animation.Animator);
    method public default void onAnimationEnd(android.animation.Animator, boolean);
    method public abstract void onAnimationEnd(android.animation.Animator);
    method public abstract void onAnimationRepeat(android.animation.Animator);
    method public default void onAnimationStart(android.animation.Animator, boolean);
    method public abstract void onAnimationStart(android.animation.Animator);
  }
@@ -3104,6 +3106,8 @@ package android.animation {
    method public void playSequentially(java.util.List<android.animation.Animator>);
    method public void playTogether(android.animation.Animator...);
    method public void playTogether(java.util.Collection<android.animation.Animator>);
    method public void reverse();
    method public void setCurrentPlayTime(long);
    method public android.animation.AnimatorSet setDuration(long);
    method public void setInterpolator(android.animation.TimeInterpolator);
    method public void setStartDelay(long);
+2 −1
Original line number Diff line number Diff line
@@ -276,8 +276,9 @@ public class AnimationHandler {
         * Run animation based on the frame time.
         * @param frameTime The frame start time, in the {@link SystemClock#uptimeMillis()} time
         *                  base.
         * @return if the animation has finished.
         */
        void doAnimationFrame(long frameTime);
        boolean doAnimationFrame(long frameTime);

        /**
         * This notifies the callback of frame commit time. Frame commit time is the time after
+92 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ import java.util.ArrayList;
 * This is the superclass for classes which provide basic support for animations which can be
 * started, ended, and have <code>AnimatorListeners</code> added to them.
 */
public abstract class Animator implements Cloneable {
public abstract class Animator implements Cloneable, AnimationHandler.AnimationFrameCallback {

    /**
     * The value used to indicate infinite duration (e.g. when Animators repeat infinitely).
@@ -464,12 +464,103 @@ public abstract class Animator implements Cloneable {
        throw new IllegalStateException("Reverse is not supported");
    }

    /**
     * @hide
     */
    @Override
    public boolean doAnimationFrame(long frameTime) {
        // TODO: Need to find a better signal than this
        return getDuration() + getStartDelay() >= frameTime;
    }

    /**
     * @hide
     */
    @Override
    public void commitAnimationFrame(long frameTime) {}


    /**
     * Internal use only.
     * This call starts the animation in regular or reverse direction without requiring them to
     * register frame callbacks. The caller will be responsible for all the subsequent animation
     * pulses. Specifically, the caller needs to call doAnimationFrame(...) for the animation on
     * every frame.
     *
     * @param inReverse whether the animation should play in reverse direction
     */
    void startWithoutPulsing(boolean inReverse) {
        if (inReverse) {
            reverse();
        } else {
            start();
        }
    }

    /**
     * Internal use only.
     * Skips the animation value to end/start, depending on whether the play direction is forward
     * or backward.
     *
     * @param inReverse whether the end value is based on a reverse direction. If yes, this is
     *                  equivalent to skip to start value in a forward playing direction.
     */
    void skipToEndValue(boolean inReverse) {}


    /**
     * Internal use only.
     *
     * Returns whether the animation has start/end values setup. For most of the animations, this
     * should always be true. For ObjectAnimators, the start values are setup in the initialization
     * of the animation.
     */
    boolean isInitialized() {
        return true;
    }

    /**
     * Internal use only.
     */
    void animateBasedOnPlayTime(long currentPlayTime, long lastPlayTime, boolean inReverse) {}

    /**
     * <p>An animation listener receives notifications from an animation.
     * Notifications indicate animation related events, such as the end or the
     * repetition of the animation.</p>
     */
    public static interface AnimatorListener {

        /**
         * <p>Notifies the start of the animation as well as the animation's overall play direction.
         * This method's default behavior is to call {@link #onAnimationStart(Animator)}. This
         * method can be overridden, though not required, to get the additional play direction info
         * when an animation starts. Skipping calling super when overriding this method results in
         * {@link #onAnimationStart(Animator)} not getting called.
         *
         * @param animation The started animation.
         * @param isReverse Whether the animation is playing in reverse.
         */
        default void onAnimationStart(Animator animation, boolean isReverse) {
            onAnimationStart(animation);
        }

        /**
         * <p>Notifies the end of the animation. This callback is not invoked
         * for animations with repeat count set to INFINITE.</p>
         *
         * <p>This method's default behavior is to call {@link #onAnimationEnd(Animator)}. This
         * method can be overridden, though not required, to get the additional play direction info
         * when an animation ends. Skipping calling super when overriding this method results in
         * {@link #onAnimationEnd(Animator)} not getting called.
         *
         * @param animation The animation which reached its end.
         * @param isReverse Whether the animation is playing in reverse.
         */
        default void onAnimationEnd(Animator animation, boolean isReverse) {
            onAnimationEnd(animation);
        }

        /**
         * <p>Notifies the start of the animation.</p>
         *
Loading