diff options
| -rw-r--r-- | core/api/current.txt | 7 | ||||
| -rw-r--r-- | core/api/test-current.txt | 3 | ||||
| -rw-r--r-- | core/java/android/animation/ValueAnimator.java | 101 |
3 files changed, 105 insertions, 6 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 3a6fc590648e..c50fec411e57 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -3901,6 +3901,7 @@ package android.animation { method public Object getAnimatedValue(String); method public long getCurrentPlayTime(); method public long getDuration(); + method @FloatRange(from=0, to=1) public static float getDurationScale(); method public static long getFrameDelay(); method public int getRepeatCount(); method public int getRepeatMode(); @@ -3912,6 +3913,7 @@ package android.animation { method public static android.animation.ValueAnimator ofInt(int...); method public static android.animation.ValueAnimator ofObject(android.animation.TypeEvaluator, java.lang.Object...); method public static android.animation.ValueAnimator ofPropertyValuesHolder(android.animation.PropertyValuesHolder...); + method public static boolean registerDurationScaleChangeListener(@NonNull android.animation.ValueAnimator.DurationScaleChangeListener); method public void removeAllUpdateListeners(); method public void removeUpdateListener(android.animation.ValueAnimator.AnimatorUpdateListener); method public void reverse(); @@ -3928,6 +3930,7 @@ package android.animation { method public void setRepeatMode(int); method public void setStartDelay(long); method public void setValues(android.animation.PropertyValuesHolder...); + method public static boolean unregisterDurationScaleChangeListener(@NonNull android.animation.ValueAnimator.DurationScaleChangeListener); field public static final int INFINITE = -1; // 0xffffffff field public static final int RESTART = 1; // 0x1 field public static final int REVERSE = 2; // 0x2 @@ -3937,6 +3940,10 @@ package android.animation { method public void onAnimationUpdate(@NonNull android.animation.ValueAnimator); } + public static interface ValueAnimator.DurationScaleChangeListener { + method public void onChanged(float); + } + } package android.annotation { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 9757b2ff318f..3a1bf6406e5c 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -95,8 +95,7 @@ package android.accessibilityservice { package android.animation { public class ValueAnimator extends android.animation.Animator { - method public static float getDurationScale(); - method public static void setDurationScale(float); + method @MainThread public static void setDurationScale(@FloatRange(from=0, to=1) float); } } diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 06b424bcb417..bca6b6a0ddd0 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -17,7 +17,9 @@ package android.animation; import android.annotation.CallSuper; +import android.annotation.FloatRange; import android.annotation.IntDef; +import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; @@ -35,8 +37,10 @@ import android.view.animation.LinearInterpolator; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; /** * This class provides a simple timing engine for running animations @@ -91,6 +95,9 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) private static float sDurationScale = 1.0f; + private static final ArrayList<WeakReference<DurationScaleChangeListener>> + sDurationScaleChangeListeners = new ArrayList<>(); + /** * Internal variables * NOTE: This object implements the clone() method, making a deep copy of any referenced @@ -308,20 +315,92 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio */ @UnsupportedAppUsage @TestApi - public static void setDurationScale(float durationScale) { + @MainThread + public static void setDurationScale(@FloatRange(from = 0, to = 1) float durationScale) { sDurationScale = durationScale; + List<WeakReference<DurationScaleChangeListener>> listenerCopy; + + synchronized (sDurationScaleChangeListeners) { + listenerCopy = new ArrayList<>(sDurationScaleChangeListeners); + } + + for (WeakReference<DurationScaleChangeListener> listenerRef : listenerCopy) { + final DurationScaleChangeListener listener = listenerRef.get(); + if (listener != null) { + listener.onChanged(durationScale); + } + } } /** - * @hide + * Returns the system-wide scaling factor for Animator-based animations. + * + * This affects both the start delay and duration of all such animations. Setting to 0 will + * cause animations to end immediately. The default value is 1.0f. + * + * @return the duration scale. */ - @UnsupportedAppUsage - @TestApi + @FloatRange(from = 0, to = 1) public static float getDurationScale() { return sDurationScale; } /** + * Registers a {@link DurationScaleChangeListener} + * + * This listens for changes to the system-wide scaling factor for Animator-based animations. + * Listeners will be called on the main thread. + * + * @param listener the listener to register. + * @return true if the listener was registered. + */ + public static boolean registerDurationScaleChangeListener( + @NonNull DurationScaleChangeListener listener) { + int posToReplace = -1; + synchronized (sDurationScaleChangeListeners) { + for (int i = 0; i < sDurationScaleChangeListeners.size(); i++) { + final WeakReference<DurationScaleChangeListener> ref = + sDurationScaleChangeListeners.get(i); + if (ref.get() == null) { + if (posToReplace == -1) { + posToReplace = i; + } + } else if (ref.get() == listener) { + return false; + } + } + if (posToReplace != -1) { + sDurationScaleChangeListeners.set(posToReplace, new WeakReference<>(listener)); + return true; + } else { + return sDurationScaleChangeListeners.add(new WeakReference<>(listener)); + } + } + } + + /** + * Unregisters a DurationScaleChangeListener. + * + * @see #registerDurationScaleChangeListener(DurationScaleChangeListener) + * @param listener the listener to unregister. + * @return true if the listener was unregistered. + */ + public static boolean unregisterDurationScaleChangeListener( + @NonNull DurationScaleChangeListener listener) { + synchronized (sDurationScaleChangeListeners) { + WeakReference<DurationScaleChangeListener> listenerRefToRemove = null; + for (WeakReference<DurationScaleChangeListener> listenerRef : + sDurationScaleChangeListeners) { + if (listenerRef.get() == listener) { + listenerRefToRemove = listenerRef; + break; + } + } + return sDurationScaleChangeListeners.remove(listenerRefToRemove); + } + } + + /** * Returns whether animators are currently enabled, system-wide. By default, all * animators are enabled. This can change if either the user sets a Developer Option * to set the animator duration scale to 0 or by Battery Savery mode being enabled @@ -1709,4 +1788,18 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio public void setAnimationHandler(@Nullable AnimationHandler animationHandler) { mAnimationHandler = animationHandler; } + + /** + * Listener interface for the system-wide scaling factor for Animator-based animations. + * + * @see #registerDurationScaleChangeListener(DurationScaleChangeListener) + * @see #unregisterDurationScaleChangeListener(DurationScaleChangeListener) + */ + public interface DurationScaleChangeListener { + /** + * Called when the duration scale changes. + * @param scale the duration scalel + */ + void onChanged(float scale); + } } |