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

Commit 54276ad3 authored by Chet Haase's avatar Chet Haase Committed by Android Git Automerger
Browse files

am cd89feb9: Merge "pause/resume for Animators" into klp-dev

* commit 'cd89feb9':
  pause/resume for Animators
parents afa1231e cd89feb9
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -2338,17 +2338,23 @@ package android.animation {
  public abstract class Animator implements java.lang.Cloneable {
    ctor public Animator();
    method public void addListener(android.animation.Animator.AnimatorListener);
    method public void addPauseListener(android.animation.Animator.AnimatorPauseListener);
    method public void cancel();
    method public android.animation.Animator clone();
    method public void end();
    method public abstract long getDuration();
    method public android.animation.TimeInterpolator getInterpolator();
    method public java.util.ArrayList<android.animation.Animator.AnimatorListener> getListeners();
    method public java.util.ArrayList<android.animation.Animator.AnimatorPauseListener> getPauseListeners();
    method public abstract long getStartDelay();
    method public boolean isPaused();
    method public abstract boolean isRunning();
    method public boolean isStarted();
    method public void pause();
    method public void removeAllListeners();
    method public void removeListener(android.animation.Animator.AnimatorListener);
    method public void removePauseListener(android.animation.Animator.AnimatorPauseListener);
    method public void resume();
    method public abstract android.animation.Animator setDuration(long);
    method public abstract void setInterpolator(android.animation.TimeInterpolator);
    method public abstract void setStartDelay(long);
@@ -2365,16 +2371,23 @@ package android.animation {
    method public abstract void onAnimationStart(android.animation.Animator);
  }
  public static abstract interface Animator.AnimatorPauseListener {
    method public abstract void onAnimationPause(android.animation.Animator);
    method public abstract void onAnimationResume(android.animation.Animator);
  }
  public class AnimatorInflater {
    ctor public AnimatorInflater();
    method public static android.animation.Animator loadAnimator(android.content.Context, int) throws android.content.res.Resources.NotFoundException;
  }
  public abstract class AnimatorListenerAdapter implements android.animation.Animator.AnimatorListener {
  public abstract class AnimatorListenerAdapter implements android.animation.Animator.AnimatorListener android.animation.Animator.AnimatorPauseListener {
    ctor public AnimatorListenerAdapter();
    method public void onAnimationCancel(android.animation.Animator);
    method public void onAnimationEnd(android.animation.Animator);
    method public void onAnimationPause(android.animation.Animator);
    method public void onAnimationRepeat(android.animation.Animator);
    method public void onAnimationResume(android.animation.Animator);
    method public void onAnimationStart(android.animation.Animator);
  }
+149 −2
Original line number Diff line number Diff line
@@ -29,6 +29,17 @@ public abstract class Animator implements Cloneable {
     */
    ArrayList<AnimatorListener> mListeners = null;

    /**
     * The set of listeners to be sent pause/resume events through the life
     * of an animation.
     */
    ArrayList<AnimatorPauseListener> mPauseListeners = null;

    /**
     * Whether this animator is currently in a paused state.
     */
    boolean mPaused = false;

    /**
     * Starts this animation. If the animation has a nonzero startDelay, the animation will start
     * running after that delay elapses. A non-delayed animation will have its initial
@@ -68,6 +79,66 @@ public abstract class Animator implements Cloneable {
    public void end() {
    }

    /**
     * Pauses a running animation. This method should only be called on the same thread on
     * which the animation was started. If the animation has not yet been {@link
     * #isStarted() started} or has since ended, then the call is ignored. Paused
     * animations can be resumed by calling {@link #resume()}.
     *
     * @see #resume()
     * @see #isPaused()
     * @see AnimatorPauseListener
     */
    public void pause() {
        if (isStarted() && !mPaused) {
            mPaused = true;
            if (mPauseListeners != null) {
                ArrayList<AnimatorPauseListener> tmpListeners =
                        (ArrayList<AnimatorPauseListener>) mPauseListeners.clone();
                int numListeners = tmpListeners.size();
                for (int i = 0; i < numListeners; ++i) {
                    tmpListeners.get(i).onAnimationPause(this);
                }
            }
        }
    }

    /**
     * Resumes a paused animation, causing the animator to pick up where it left off
     * when it was paused. This method should only be called on the same thread on
     * which the animation was started. Calls to resume() on an animator that is
     * not currently paused will be ignored.
     *
     * @see #pause()
     * @see #isPaused()
     * @see AnimatorPauseListener
     */
    public void resume() {
        if (mPaused) {
            mPaused = false;
            if (mPauseListeners != null) {
                ArrayList<AnimatorPauseListener> tmpListeners =
                        (ArrayList<AnimatorPauseListener>) mPauseListeners.clone();
                int numListeners = tmpListeners.size();
                for (int i = 0; i < numListeners; ++i) {
                    tmpListeners.get(i).onAnimationResume(this);
                }
            }
        }
    }

    /**
     * Returns whether this animator is currently in a paused state.
     *
     * @return True if the animator is currently paused, false otherwise.
     *
     * @see #pause()
     * @see #resume()
     */
    public boolean isPaused() {
        return mPaused;
    }

    /**
     * The amount of time, in milliseconds, to delay processing the animation
     * after {@link #start()} is called.
@@ -179,16 +250,59 @@ public abstract class Animator implements Cloneable {
        return mListeners;
    }

    /**
     * Adds a pause listener to this animator.
     *
     * @param listener the listener to be added to the current set of pause listeners
     * for this animation.
     */
    public void addPauseListener(AnimatorPauseListener listener) {
        if (mPauseListeners == null) {
            mPauseListeners = new ArrayList<AnimatorPauseListener>();
        }
        mPauseListeners.add(listener);
    }

    /**
     * Removes a pause listener from the set listening to this animation.
     *
     * @param listener the listener to be removed from the current set of pause
     * listeners for this animation.
     */
    public void removePauseListener(AnimatorPauseListener listener) {
        if (mPauseListeners == null) {
            return;
        }
        mPauseListeners.remove(listener);
        if (mPauseListeners.size() == 0) {
            mPauseListeners = null;
        }
    }

    /**
     * Gets the set of {@link AnimatorPauseListener} objects that are currently
     * listening for pause/resume events on this animator.
     *
     * @return ArrayList<AnimatorListener> The set of pause listeners.
     */
    public ArrayList<AnimatorPauseListener> getPauseListeners() {
        return mPauseListeners;
    }

    /**
     * Removes all listeners from this object. This is equivalent to calling
     * <code>getListeners()</code> followed by calling <code>clear()</code> on the
     * returned list of listeners.
     * {@link #getListeners()} and {@link #getPauseListeners()} followed by calling
     * {@link ArrayList#clear()} on the returned lists of listeners.
     */
    public void removeAllListeners() {
        if (mListeners != null) {
            mListeners.clear();
            mListeners = null;
        }
        if (mPauseListeners != null) {
            mPauseListeners.clear();
            mPauseListeners = null;
        }
    }

    @Override
@@ -203,6 +317,14 @@ public abstract class Animator implements Cloneable {
                    anim.mListeners.add(oldListeners.get(i));
                }
            }
            if (mPauseListeners != null) {
                ArrayList<AnimatorPauseListener> oldListeners = mPauseListeners;
                anim.mPauseListeners = new ArrayList<AnimatorPauseListener>();
                int numListeners = oldListeners.size();
                for (int i = 0; i < numListeners; ++i) {
                    anim.mPauseListeners.add(oldListeners.get(i));
                }
            }
            return anim;
        } catch (CloneNotSupportedException e) {
           throw new AssertionError();
@@ -280,4 +402,29 @@ public abstract class Animator implements Cloneable {
         */
        void onAnimationRepeat(Animator animation);
    }

    /**
     * A pause listener receives notifications from an animation when the
     * animation is {@link #pause() paused} or {@link #resume() resumed}.
     *
     * @see #addPauseListener(AnimatorPauseListener)
     */
    public static interface AnimatorPauseListener {
        /**
         * <p>Notifies that the animation was paused.</p>
         *
         * @param animation The animaton being paused.
         * @see #pause()
         */
        void onAnimationPause(Animator animation);

        /**
         * <p>Notifies that the animation was resumed, after being
         * previously paused.</p>
         *
         * @param animation The animation being resumed.
         * @see #resume()
         */
        void onAnimationResume(Animator animation);
    }
}
+15 −1
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ package android.animation;
 * Any custom listener that cares only about a subset of the methods of this listener can
 * simply subclass this adapter class instead of implementing the interface directly.
 */
public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener {
public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener,
        Animator.AnimatorPauseListener {

    /**
     * {@inheritDoc}
@@ -51,4 +52,17 @@ public abstract class AnimatorListenerAdapter implements Animator.AnimatorListen
    public void onAnimationStart(Animator animation) {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onAnimationPause(Animator animation) {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onAnimationResume(Animator animation) {
    }
}
+33 −0
Original line number Diff line number Diff line
@@ -455,6 +455,36 @@ public final class AnimatorSet extends Animator {
        }
    }

    @Override
    public void pause() {
        boolean previouslyPaused = mPaused;
        super.pause();
        if (!previouslyPaused && mPaused) {
            if (mDelayAnim != null) {
                mDelayAnim.pause();
            } else {
                for (Node node : mNodes) {
                    node.animation.pause();
                }
            }
        }
    }

    @Override
    public void resume() {
        boolean previouslyPaused = mPaused;
        super.resume();
        if (previouslyPaused && !mPaused) {
            if (mDelayAnim != null) {
                mDelayAnim.resume();
            } else {
                for (Node node : mNodes) {
                    node.animation.resume();
                }
            }
        }
    }

    /**
     * {@inheritDoc}
     *
@@ -467,6 +497,7 @@ public final class AnimatorSet extends Animator {
    public void start() {
        mTerminated = false;
        mStarted = true;
        mPaused = false;

        if (mDuration >= 0) {
            // If the duration was set on this AnimatorSet, pass it along to all child animations
@@ -549,6 +580,7 @@ public final class AnimatorSet extends Animator {
                            mPlayingSet.add(node.animation);
                        }
                    }
                    mDelayAnim = null;
                }
            });
            mDelayAnim.start();
@@ -787,6 +819,7 @@ public final class AnimatorSet extends Animator {
                        }
                    }
                    mAnimatorSet.mStarted = false;
                    mAnimatorSet.mPaused = false;
                }
            }
        }
+60 −2
Original line number Diff line number Diff line
@@ -80,6 +80,20 @@ public class ValueAnimator extends Animator {
     */
    long mSeekTime = -1;

    /**
     * Set on the next frame after pause() is called, used to calculate a new startTime
     * or delayStartTime which allows the animator to continue from the point at which
     * it was paused. If negative, has not yet been set.
     */
    private long mPauseTime;

    /**
     * Set when an animator is resumed. This triggers logic in the next frame which
     * actually resumes the animator.
     */
    private boolean mResumed = false;


    // The static sAnimationHandler processes the internal timing loop on which all animations
    // are based
    /**
@@ -147,7 +161,7 @@ public class ValueAnimator extends Animator {
    private boolean mStarted = false;

    /**
     * Tracks whether we've notified listeners of the onAnimationSTart() event. This can be
     * Tracks whether we've notified listeners of the onAnimationStart() event. This can be
     * complex to keep track of since we notify listeners at different times depending on
     * startDelay and whether start() was called before end().
     */
@@ -914,6 +928,7 @@ public class ValueAnimator extends Animator {
        mPlayingState = STOPPED;
        mStarted = true;
        mStartedDelay = false;
        mPaused = false;
        AnimationHandler animationHandler = getOrCreateAnimationHandler();
        animationHandler.mPendingAnimations.add(this);
        if (mStartDelay == 0) {
@@ -970,6 +985,24 @@ public class ValueAnimator extends Animator {
        endAnimation(handler);
    }

    @Override
    public void resume() {
        if (mPaused) {
            mResumed = true;
        }
        super.resume();
    }

    @Override
    public void pause() {
        boolean previouslyPaused = mPaused;
        super.pause();
        if (!previouslyPaused && mPaused) {
            mPauseTime = -1;
            mResumed = false;
        }
    }

    @Override
    public boolean isRunning() {
        return (mPlayingState == RUNNING || mRunning);
@@ -1008,6 +1041,7 @@ public class ValueAnimator extends Animator {
        handler.mPendingAnimations.remove(this);
        handler.mDelayedAnims.remove(this);
        mPlayingState = STOPPED;
        mPaused = false;
        if ((mStarted || mRunning) && mListeners != null) {
            if (!mRunning) {
                // If it's not yet running, then start listeners weren't called. Call them now.
@@ -1071,6 +1105,18 @@ public class ValueAnimator extends Animator {
            mStartedDelay = true;
            mDelayStartTime = currentTime;
        } else {
            if (mPaused) {
                if (mPauseTime < 0) {
                    mPauseTime = currentTime;
                }
                return false;
            } else if (mResumed) {
                mResumed = false;
                if (mPauseTime > 0) {
                    // Offset by the duration that the animation was paused
                    mDelayStartTime += (currentTime - mPauseTime);
                }
            }
            long deltaTime = currentTime - mDelayStartTime;
            if (deltaTime > mStartDelay) {
                // startDelay ended - start the anim and record the
@@ -1093,7 +1139,7 @@ public class ValueAnimator extends Animator {
     *
     * @param currentTime The current time, as tracked by the static timing handler
     * @return true if the animation's duration, including any repetitions due to
     * <code>repeatCount</code> has been exceeded and the animation should be ended.
     * <code>repeatCount</code>, has been exceeded and the animation should be ended.
     */
    boolean animationFrame(long currentTime) {
        boolean done = false;
@@ -1148,6 +1194,18 @@ public class ValueAnimator extends Animator {
                mSeekTime = -1;
            }
        }
        if (mPaused) {
            if (mPauseTime < 0) {
                mPauseTime = frameTime;
            }
            return false;
        } else if (mResumed) {
            mResumed = false;
            if (mPauseTime > 0) {
                // Offset by the duration that the animation was paused
                mStartTime += (frameTime - mPauseTime);
            }
        }
        // The frame time might be before the start time during the first frame of
        // an animation.  The "current time" must always be on or after the start
        // time to avoid animating frames at negative time intervals.  In practice, this
Loading