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

Commit 02ecf040 authored by Doris Liu's avatar Doris Liu Committed by Android (Google) Code Review
Browse files

Merge "Distance based animation duration"

parents e144bb15 0084e370
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -525,6 +525,7 @@ package android {
    field public static final int dropDownWidth = 16843362; // 0x1010262
    field public static final int duplicateParentState = 16842985; // 0x10100e9
    field public static final int duration = 16843160; // 0x1010198
    field public static final int durationScaleHint = 16844014; // 0x10104ee
    field public static final int editTextBackground = 16843602; // 0x1010352
    field public static final int editTextColor = 16843601; // 0x1010351
    field public static final int editTextPreferenceStyle = 16842898; // 0x1010092
@@ -2879,6 +2880,7 @@ package android.animation {
    method public void cancel();
    method public android.animation.Animator clone();
    method public void end();
    method public long getDistanceBasedDuration();
    method public abstract long getDuration();
    method public android.animation.TimeInterpolator getInterpolator();
    method public java.util.ArrayList<android.animation.Animator.AnimatorListener> getListeners();
@@ -2892,12 +2894,16 @@ package android.animation {
    method public void removePauseListener(android.animation.Animator.AnimatorPauseListener);
    method public void resume();
    method public abstract android.animation.Animator setDuration(long);
    method public void setDurationScaleHint(int, android.content.res.Resources);
    method public abstract void setInterpolator(android.animation.TimeInterpolator);
    method public abstract void setStartDelay(long);
    method public void setTarget(java.lang.Object);
    method public void setupEndValues();
    method public void setupStartValues();
    method public void start();
    field public static final int HINT_DISTANCE_DEFINED_IN_DP = 2; // 0x2
    field public static final int HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE = 1; // 0x1
    field public static final int HINT_NO_SCALE = 0; // 0x0
  }
  public static abstract interface Animator.AnimatorListener {
+6 −0
Original line number Diff line number Diff line
@@ -598,6 +598,7 @@ package android {
    field public static final int dropDownWidth = 16843362; // 0x1010262
    field public static final int duplicateParentState = 16842985; // 0x10100e9
    field public static final int duration = 16843160; // 0x1010198
    field public static final int durationScaleHint = 16844014; // 0x10104ee
    field public static final int editTextBackground = 16843602; // 0x1010352
    field public static final int editTextColor = 16843601; // 0x1010351
    field public static final int editTextPreferenceStyle = 16842898; // 0x1010092
@@ -2959,6 +2960,7 @@ package android.animation {
    method public void cancel();
    method public android.animation.Animator clone();
    method public void end();
    method public long getDistanceBasedDuration();
    method public abstract long getDuration();
    method public android.animation.TimeInterpolator getInterpolator();
    method public java.util.ArrayList<android.animation.Animator.AnimatorListener> getListeners();
@@ -2972,12 +2974,16 @@ package android.animation {
    method public void removePauseListener(android.animation.Animator.AnimatorPauseListener);
    method public void resume();
    method public abstract android.animation.Animator setDuration(long);
    method public void setDurationScaleHint(int, android.content.res.Resources);
    method public abstract void setInterpolator(android.animation.TimeInterpolator);
    method public abstract void setStartDelay(long);
    method public void setTarget(java.lang.Object);
    method public void setupEndValues();
    method public void setupStartValues();
    method public void start();
    field public static final int HINT_DISTANCE_DEFINED_IN_DP = 2; // 0x2
    field public static final int HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE = 1; // 0x1
    field public static final int HINT_NO_SCALE = 0; // 0x0
  }
  public static abstract interface Animator.AnimatorListener {
+118 −0
Original line number Diff line number Diff line
@@ -16,7 +16,12 @@

package android.animation;

import android.content.res.Configuration;
import android.content.res.ConstantState;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.animation.AnimationUtils;

import java.util.ArrayList;

@@ -25,6 +30,29 @@ import java.util.ArrayList;
 * started, ended, and have <code>AnimatorListeners</code> added to them.
 */
public abstract class Animator implements Cloneable {
    /**
     * Set this hint when duration for the animation does not need to be scaled. By default, no
     * scaling is applied to the duration.
     */
    public static final int HINT_NO_SCALE = 0;

    /**
     * Set this scale hint (using {@link #setDurationScaleHint(int, Resources)} when the animation's
     * moving distance is proportional to the screen size. (e.g. a view coming in from the bottom of
     * the screen to top/center). With this scale hint set, the animation duration will be
     * automatically scaled based on screen size.
     */
    public static final int HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE = 1;

    /**
     * Set this scale hint (using {@link #setDurationScaleHint(int, Resources)}) if the animation
     * has pre-defined moving distance in dp that does not vary from device to device. This is
     * extremely useful when the animation needs to run on both phones/tablets and TV, because TV
     * has inflated dp and therefore will have a longer visual arc for the same animation than on
     * the phone. This hint is used to calculate a scaling factor to compensate for different
     * visual arcs while maintaining the same angular velocity for the animation.
     */
    public static final int HINT_DISTANCE_DEFINED_IN_DP = 2;

    /**
     * The set of listeners to be sent events through the life of an animation.
@@ -54,6 +82,24 @@ public abstract class Animator implements Cloneable {
     */
    private AnimatorConstantState mConstantState;

    /**
     * Scaling factor for an animation that moves across the whole screen.
     */
    float mScreenSizeBasedDurationScale = 1.0f;

    /**
     * Scaling factor for an animation that is defined to move the same amount of dp across all
     * devices.
     */
    float mDpBasedDurationScale = 1.0f;

    /**
     * By default, the scaling assumes the animation moves across the entire screen.
     */
    int mDurationScaleHint = HINT_NO_SCALE;

    private final static boolean ANIM_DEBUG = 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
@@ -183,6 +229,78 @@ public abstract class Animator implements Cloneable {
     */
    public abstract long getDuration();

    /**
     * Hints how duration scaling factor should be calculated. The duration will not be scaled when
     * hint is set to {@link #HINT_NO_SCALE}. Otherwise, the duration will be automatically scaled
     * per device to achieve the same look and feel across different devices. In order to do
     * that, the same angular velocity of the animation will be needed on different devices in
     * users' field of view. Therefore, the duration scale factor is determined by the ratio of the
     * angular movement on current devices to that on the baseline device (i.e. Nexus 5).
     *
     * @param hint an indicator on how the animation is defined. The hint could be
     *             {@link #HINT_NO_SCALE}, {@link #HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE} or
     *             {@link #HINT_DISTANCE_DEFINED_IN_DP}.
     * @param res The resources {@see android.content.res.Resources} for getting display metrics
     */
    public void setDurationScaleHint(int hint, Resources res) {
        if (ANIM_DEBUG) {
            Log.d("ANIM_DEBUG", "distance based duration hint: " + hint);
        }
        if (hint == mDurationScaleHint) {
            return;
        }
        mDurationScaleHint = hint;
        if (hint != HINT_NO_SCALE) {
            int uiMode = res.getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK;
            DisplayMetrics metrics = res.getDisplayMetrics();
            float width = metrics.widthPixels / metrics.xdpi;
            float height = metrics.heightPixels / metrics.ydpi;
            float viewingDistance = AnimationUtils.getViewingDistance(width, height, uiMode);
            if (ANIM_DEBUG) {
                Log.d("ANIM_DEBUG", "width, height, viewing distance, uimode: "
                        + width + ", " + height + ", " + viewingDistance + ", " + uiMode);
            }
            mScreenSizeBasedDurationScale = AnimationUtils
                    .getScreenSizeBasedDurationScale(width, height, viewingDistance);
            mDpBasedDurationScale = AnimationUtils.getDpBasedDurationScale(
                    metrics.density, metrics.xdpi, viewingDistance);
            if (ANIM_DEBUG) {
                Log.d("ANIM_DEBUG", "screen based scale, dp based scale: " +
                        mScreenSizeBasedDurationScale + ", " + mDpBasedDurationScale);
            }
        }
    }

    // Copies duration scale hint and scaling factors to the new animation.
    void copyDurationScaleInfoTo(Animator anim) {
        anim.mDurationScaleHint = mDurationScaleHint;
        anim.mScreenSizeBasedDurationScale = mScreenSizeBasedDurationScale;
        anim.mDpBasedDurationScale = mDpBasedDurationScale;
    }

    /**
     * @return The scaled duration calculated based on distance of movement (as defined by the
     * animation) and perceived velocity (derived from the duration set on the animation for
     * baseline device)
     */
    public long getDistanceBasedDuration() {
        return (long) (getDuration() * getDistanceBasedDurationScale());
    }

    /**
     * @return scaling factor of duration based on the duration scale hint. A scaling factor of 1
     * means no scaling will be applied to the duration.
     */
    float getDistanceBasedDurationScale() {
        if (mDurationScaleHint == HINT_DISTANCE_PROPORTIONAL_TO_SCREEN_SIZE) {
            return mScreenSizeBasedDurationScale;
        } else if (mDurationScaleHint == HINT_DISTANCE_DEFINED_IN_DP) {
            return mDpBasedDurationScale;
        } else {
            return 1f;
        }
    }

    /**
     * The time interpolator used in calculating the elapsed fraction of the
     * animation. The interpolator determines whether the animation runs with
+13 −0
Original line number Diff line number Diff line
@@ -70,6 +70,13 @@ public class AnimatorInflater {
    private static final int VALUE_TYPE_COLOR       = 3;
    private static final int VALUE_TYPE_UNDEFINED   = 4;

    /**
     * Enum values used in XML attributes to indicate the duration scale hint.
     */
    private static final int HINT_NO_SCALE                  = 0;
    private static final int HINT_PROPORTIONAL_TO_SCREEN    = 1;
    private static final int HINT_DEFINED_IN_DP             = 2;

    private static final boolean DBG_ANIMATOR_INFLATER = false;

    // used to calculate changing configs for resource references
@@ -691,6 +698,9 @@ public class AnimatorInflater {
                int ordering = a.getInt(R.styleable.AnimatorSet_ordering, TOGETHER);
                createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering,
                        pixelSize);
                final int hint = a.getInt(R.styleable.Animator_durationScaleHint,
                        HINT_NO_SCALE);
                anim.setDurationScaleHint(hint, res);
                a.recycle();
            } else if (name.equals("propertyValuesHolder")) {
                PropertyValuesHolder[] values = loadValues(res, theme, parser,
@@ -1027,6 +1037,9 @@ public class AnimatorInflater {
            anim.setInterpolator(interpolator);
        }

        final int hint = arrayAnimator.getInt(R.styleable.Animator_durationScaleHint,
                HINT_NO_SCALE);
        anim.setDurationScaleHint(hint, res);
        arrayAnimator.recycle();
        if (arrayObjectAnimator != null) {
            arrayObjectAnimator.recycle();
+1 −0
Original line number Diff line number Diff line
@@ -519,6 +519,7 @@ public final class AnimatorSet extends Animator {

        for (Node node : mNodes) {
            node.animation.setAllowRunningAsynchronously(false);
            copyDurationScaleInfoTo(node.animation);
        }

        if (mDuration >= 0) {
Loading