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

Commit 602e4d38 authored by Chet Haase's avatar Chet Haase
Browse files

Adding animation facilities to simplify layout transitions

Change-Id: I70992a0dff6a75727f51abcfdfc7d7f2c2a8c101
parent 81b5db04
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -20080,6 +20080,17 @@
 visibility="public"
>
</method>
<method name="getDuration"
 return="long"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getFrameDelay"
 return="long"
 abstract="false"
@@ -20091,6 +20102,17 @@
 visibility="public"
>
</method>
<method name="getInterpolator"
 return="android.view.animation.Interpolator"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getRepeatCount"
 return="int"
 abstract="false"
+62 −47
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.animation;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.view.animation.AccelerateDecelerateInterpolator;
@@ -197,15 +198,13 @@ public class Animator<T> extends Animatable {
    /**
     * The property/value sets being animated.
     */
    HashMap<String, PropertyValuesHolder> mValues;
    PropertyValuesHolder[] mValues;

    /**
     * This value is used in the simple/common case of animating just one value; the user
     * may call getAnimatedValue(), which should return the value of the first (and only)
     * ProeprtyValuesHolder animated value, which is looked up using this string.
     * A hashmap of the PropertyValuesHolder objects. This map is used to lookup animated values
     * by property name during calls to getAnimatedValue(String).
     */
    String mFirstPropertyName;

    HashMap<String, PropertyValuesHolder> mValuesMap;

    /**
     * The type of the values, as determined by the valueFrom/valueTo properties.
@@ -290,11 +289,11 @@ public class Animator<T> extends Animatable {
                break;
        }

        mValues = new HashMap<String, PropertyValuesHolder>(1);
        mFirstPropertyName = "";
        PropertyValuesHolder valuesHolder = new PropertyValuesHolder(mFirstPropertyName,
                valueFrom, valueTo);
        mValues.put(mFirstPropertyName, valuesHolder);
        PropertyValuesHolder valuesHolder = new PropertyValuesHolder("", valueFrom, valueTo);
        mValues = new PropertyValuesHolder[1];
        mValues[0] = valuesHolder;
        mValuesMap = new HashMap<String, PropertyValuesHolder>(1);
        mValuesMap.put("", valuesHolder);

        mRepeatCount = a.getInt(com.android.internal.R.styleable.Animator_repeatCount, mRepeatCount);
        mRepeatMode = a.getInt(com.android.internal.R.styleable.Animator_repeatMode, RESTART);
@@ -323,15 +322,11 @@ public class Animator<T> extends Animatable {

    public void setValues(PropertyValuesHolder... values) {
        int numValues = values.length;
        mValues = new HashMap<String, PropertyValuesHolder>(numValues);
        mValues = values;
        mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
        for (int i = 0; i < numValues; ++i) {
            PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
            mValues.put(valuesHolder.getPropertyName(), valuesHolder);
        }
        if (numValues > 0 && values[0] != null) {
            mFirstPropertyName = ((PropertyValuesHolder) values[0]).getPropertyName();
        } else {
            mFirstPropertyName = "";
            mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
        }
    }

@@ -348,28 +343,14 @@ public class Animator<T> extends Animatable {
     * @param values The set of values to animate between.
     */
    public void setValues(T... values) {
        if (values[0] instanceof PropertyValuesHolder) {
            int numValues = values.length;
            mValues = new HashMap<String, PropertyValuesHolder>(numValues);
            for (int i = 0; i < numValues; ++i) {
                PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
                mValues.put(valuesHolder.getPropertyName(), valuesHolder);
            }
            if (numValues > 0 && values[0] != null) {
                mFirstPropertyName = ((PropertyValuesHolder) values[0]).getPropertyName();
            } else {
                mFirstPropertyName = "";
            }
        } else {
            if (mValues == null) {
        if (mValues == null || mValues.length == 0) {
            setValues(new PropertyValuesHolder[]{
                    new PropertyValuesHolder("", (Object[])values)});
        } else {
                PropertyValuesHolder valuesHolder = mValues.get(mFirstPropertyName);
            PropertyValuesHolder valuesHolder = mValues[0];
            valuesHolder.setValues(values);
        }
    }
    }

    /**
     * This function is called immediately before processing the first animation
@@ -382,8 +363,9 @@ public class Animator<T> extends Animatable {
     *  that internal mechanisms for the animation are set up correctly.</p>
     */
    void initAnimation() {
        for (PropertyValuesHolder pvHolder: mValues.values()) {
            pvHolder.init();
        int numValues = mValues.length;
        for (int i = 0; i < numValues; ++i) {
            mValues[i].init();
        }
        mCurrentIteration = 0;
        mInitialized = true;
@@ -394,8 +376,8 @@ public class Animator<T> extends Animatable {
     * be between 0 and the total duration of the animation, including any repetition. If
     * the animation has not yet been started, then it will not advance forward after it is
     * set to this time; it will simply set the time to this value and perform any appropriate
     * actions based on that time. If the animation is already running, then seek() will
     * set the current playing time to this value and continue playing from that point.
     * actions based on that time. If the animation is already running, then setCurrentPlayTime()
     * will set the current playing time to this value and continue playing from that point.
     *
     * @param playTime The time, in milliseconds, to which the animation is advanced or rewound.
     */
@@ -587,7 +569,11 @@ public class Animator<T> extends Animatable {
     * returns the animated value for the first of those objects.
     */
    public Object getAnimatedValue() {
        return getAnimatedValue(mFirstPropertyName);
        if (mValues != null && mValues.length > 0) {
            return mValues[0].getAnimatedValue();
        }
        // Shouldn't get here; should always have values unless Animator was set up wrong
        return null;
    }

    /**
@@ -601,7 +587,13 @@ public class Animator<T> extends Animatable {
     * by this <code>Animator</code>.
     */
    public Object getAnimatedValue(String propertyName) {
        return mValues.get(mFirstPropertyName).getAnimatedValue();
        PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
        if (valuesHolder != null) {
            return valuesHolder.getAnimatedValue();
        } else {
            // At least avoid crashing if called with bogus propertyName
            return null;
        }
    }

    /**
@@ -690,6 +682,15 @@ public class Animator<T> extends Animatable {
        }
    }

    /**
     * Returns the timing interpolator that this Animator uses.
     *
     * @return The timing interpolator for this Animator.
     */
    public Interpolator getInterpolator() {
        return mInterpolator;
    }

    /**
     * The type evaluator to be used when calculating the animated values of this animation.
     * The system will automatically assign a float, int, or double evaluator based on the type
@@ -707,8 +708,8 @@ public class Animator<T> extends Animatable {
     * @param value the evaluator to be used this animation
     */
    public void setEvaluator(TypeEvaluator value) {
        if (value != null && mValues != null) {
            mValues.get(mFirstPropertyName).setEvaluator(value);
        if (value != null && mValues != null && mValues.length > 0) {
            mValues[0].setEvaluator(value);
        }
    }

@@ -720,6 +721,10 @@ public class Animator<T> extends Animatable {
     * @param playBackwards Whether the Animator should start playing in reverse.
     */
    private void start(boolean playBackwards) {
        if ((mStartDelay == 0) && (Thread.currentThread() == Looper.getMainLooper().getThread())) {
            // This sets the initial value of the animation, prior to actually starting it running
            setCurrentPlayTime(getCurrentPlayTime());
        }
        mPlayingBackwards = playBackwards;
        mPlayingState = STOPPED;
        sPendingAnimations.add(this);
@@ -731,6 +736,15 @@ public class Animator<T> extends Animatable {
        sAnimationHandler.sendEmptyMessage(ANIMATION_START);
    }

    /**
     * Returns the duration that this animation will run for.
     *
     * @return The length in time of the animation, in milliseconds.
     */
    public long getDuration() {
        return mDuration;
    }

    @Override
    public void start() {
        start(false);
@@ -928,8 +942,9 @@ public class Animator<T> extends Animatable {
     */
    void animateValue(float fraction) {
        fraction = mInterpolator.getInterpolation(fraction);
        for (PropertyValuesHolder valuesHolder : mValues.values()) {
            valuesHolder.calculateValue(fraction);
        int numValues = mValues.length;
        for (int i = 0; i < numValues; ++i) {
            mValues[i].calculateValue(fraction);
        }
        if (mUpdateListeners != null) {
            int numListeners = mUpdateListeners.size();
+11 −10
Original line number Diff line number Diff line
@@ -21,10 +21,7 @@ import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * This subclass of {@link Animator} provides support for animating properties on target objects.
@@ -61,10 +58,12 @@ public final class PropertyAnimator<T> extends Animator<T> {
     */
    public void setPropertyName(String propertyName) {
        if (mValues != null) {
            // should always be the case
            PropertyValuesHolder valuesHolder = mValues.get(mFirstPropertyName);
            // mValues should always be non-null
            PropertyValuesHolder valuesHolder = mValues[0];
            String oldName = valuesHolder.getPropertyName();
            valuesHolder.setPropertyName(propertyName);
            mFirstPropertyName = propertyName;
            mValuesMap.remove(oldName);
            mValuesMap.put(propertyName, valuesHolder);
        }
        mPropertyName = propertyName;
    }
@@ -184,8 +183,9 @@ public final class PropertyAnimator<T> extends Animator<T> {
    @Override
    void initAnimation() {
        super.initAnimation();
        for (PropertyValuesHolder valuesHolder : mValues.values()) {
            valuesHolder.setupSetterAndGetter(mTarget);
        int numValues = mValues.length;
        for (int i = 0; i < numValues; ++i) {
            mValues[i].setupSetterAndGetter(mTarget);
        }
    }

@@ -223,8 +223,9 @@ public final class PropertyAnimator<T> extends Animator<T> {
    @Override
    void animateValue(float fraction) {
        super.animateValue(fraction);
        for (PropertyValuesHolder valuesHolder : mValues.values()) {
            valuesHolder.setAnimatedValue(mTarget);
        int numValues = mValues.length;
        for (int i = 0; i < numValues; ++i) {
            mValues[i].setAnimatedValue(mTarget);
        }
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -261,11 +261,12 @@ public class PropertyValuesHolder<T> {
                    // Swallow the error and keep trying other variants
                }
            }
        }
            // If we got here, then no appropriate function was found
            Log.e("PropertyValuesHolder",
                    "Couldn't find setter/getter for property " + mPropertyName +
                            "with value type "+ mValueType);
        }

        return returnVal;
    }