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

Commit 984011f6 authored by George Mount's avatar George Mount
Browse files

Use optimized Keyframes for Path animations.

Bug 17005728

Change-Id: I2e109ed1a3e768e1e0286fc3950516f16509e591
parent c9991c71
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -370,14 +370,23 @@ public class AnimatorInflater {
                        + " propertyXName or propertyYName is needed for PathData");
            } else {
                Path path = PathParser.createPathFromPathData(pathData);
                Keyframe[][] keyframes = PropertyValuesHolder.createKeyframes(path, !getFloats);
                PathKeyframes keyframeSet = KeyframeSet.ofPath(path);
                Keyframes xKeyframes;
                Keyframes yKeyframes;
                if (getFloats) {
                    xKeyframes = keyframeSet.createXFloatKeyframes();
                    yKeyframes = keyframeSet.createYFloatKeyframes();
                } else {
                    xKeyframes = keyframeSet.createXIntKeyframes();
                    yKeyframes = keyframeSet.createYIntKeyframes();
                }
                PropertyValuesHolder x = null;
                PropertyValuesHolder y = null;
                if (propertyXName != null) {
                    x = PropertyValuesHolder.ofKeyframe(propertyXName, keyframes[0]);
                    x = PropertyValuesHolder.ofKeyframes(propertyXName, xKeyframes);
                }
                if (propertyYName != null) {
                    y = PropertyValuesHolder.ofKeyframe(propertyYName, keyframes[1]);
                    y = PropertyValuesHolder.ofKeyframes(propertyYName, yKeyframes);
                }
                if (x == null) {
                    oa.setValues(y);
+7 −2
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ import java.util.ArrayList;
 * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
 * Object equivalents of these primitive types.</p>
 */
class FloatKeyframeSet extends KeyframeSet {
class FloatKeyframeSet extends KeyframeSet implements Keyframes.FloatKeyframes {
    private float firstValue;
    private float lastValue;
    private float deltaValue;
@@ -58,10 +58,11 @@ class FloatKeyframeSet extends KeyframeSet {
    }

    @Override
    void invalidateCache() {
    public void invalidateCache() {
        firstTime = true;
    }

    @Override
    public float getFloatValue(float fraction) {
        if (mNumKeyframes == 2) {
            if (firstTime) {
@@ -135,5 +136,9 @@ class FloatKeyframeSet extends KeyframeSet {
        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
    }

    @Override
    public Class getType() {
        return Float.class;
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ import java.util.ArrayList;
 * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
 * Object equivalents of these primitive types.</p>
 */
class IntKeyframeSet extends KeyframeSet {
class IntKeyframeSet extends KeyframeSet implements Keyframes.IntKeyframes {
    private int firstValue;
    private int lastValue;
    private int deltaValue;
@@ -58,10 +58,11 @@ class IntKeyframeSet extends KeyframeSet {
    }

    @Override
    void invalidateCache() {
    public void invalidateCache() {
        firstTime = true;
    }

    @Override
    public int getIntValue(float fraction) {
        if (mNumKeyframes == 2) {
            if (firstTime) {
@@ -134,5 +135,9 @@ class IntKeyframeSet extends KeyframeSet {
        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue();
    }

    @Override
    public Class getType() {
        return Integer.class;
    }
}
+17 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import java.util.Arrays;
import android.animation.Keyframe.IntKeyframe;
import android.animation.Keyframe.FloatKeyframe;
import android.animation.Keyframe.ObjectKeyframe;
import android.graphics.Path;
import android.util.Log;

/**
@@ -28,7 +29,7 @@ import android.util.Log;
 * values between those keyframes for a given animation. The class internal to the animation
 * package because it is an implementation detail of how Keyframes are stored and used.
 */
class KeyframeSet {
class KeyframeSet implements Keyframes {

    int mNumKeyframes;

@@ -52,7 +53,12 @@ class KeyframeSet {
     * If subclass has variables that it calculates based on the Keyframes, it should reset them
     * when this method is called because Keyframe contents might have changed.
     */
    void invalidateCache() {
    @Override
    public void invalidateCache() {
    }

    public ArrayList<Keyframe> getKeyframes() {
        return mKeyframes;
    }

    public static KeyframeSet ofInt(int... values) {
@@ -144,6 +150,10 @@ class KeyframeSet {
        return new KeyframeSet(keyframes);
    }

    public static PathKeyframes ofPath(Path path) {
        return new PathKeyframes(path);
    }

    /**
     * Sets the TypeEvaluator to be used when calculating animated values. This object
     * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet,
@@ -156,6 +166,11 @@ class KeyframeSet {
        mEvaluator = evaluator;
    }

    @Override
    public Class getType() {
        return mFirstKeyframe.getType();
    }

    @Override
    public KeyframeSet clone() {
        ArrayList<Keyframe> keyframes = mKeyframes;
+94 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.animation;

import java.util.ArrayList;

/**
 * This interface abstracts a collection of Keyframe objects and is called by
 * ValueAnimator to calculate values between those keyframes for a given animation.
 */
interface Keyframes extends Cloneable {

    /**
     * Sets the TypeEvaluator to be used when calculating animated values. This object
     * is required only for Keyframes that are not either IntKeyframes or FloatKeyframes,
     * both of which assume their own evaluator to speed up calculations with those primitive
     * types.
     *
     * @param evaluator The TypeEvaluator to be used to calculate animated values.
     */
    void setEvaluator(TypeEvaluator evaluator);

    /**
     * @return The value type contained by the contained Keyframes.
     */
    Class getType();

    /**
     * Gets the animated value, given the elapsed fraction of the animation (interpolated by the
     * animation's interpolator) and the evaluator used to calculate in-between values. This
     * function maps the input fraction to the appropriate keyframe interval and a fraction
     * between them and returns the interpolated value. Note that the input fraction may fall
     * outside the [0-1] bounds, if the animation's interpolator made that happen (e.g., a
     * spring interpolation that might send the fraction past 1.0). We handle this situation by
     * just using the two keyframes at the appropriate end when the value is outside those bounds.
     *
     * @param fraction The elapsed fraction of the animation
     * @return The animated value.
     */
    Object getValue(float fraction);

    /**
     * If subclass has variables that it calculates based on the Keyframes, it should reset them
     * when this method is called because Keyframe contents might have changed.
     */
    void invalidateCache();

    /**
     * @return A list of all Keyframes contained by this. This may return null if this is
     * not made up of Keyframes.
     */
    ArrayList<Keyframe> getKeyframes();

    Keyframes clone();

    /**
     * A specialization of Keyframes that has integer primitive value calculation.
     */
    public interface IntKeyframes extends Keyframes {

        /**
         * Works like {@link #getValue(float)}, but returning a primitive.
         * @param fraction The elapsed fraction of the animation
         * @return The animated value.
         */
        int getIntValue(float fraction);
    }

    /**
     * A specialization of Keyframes that has float primitive value calculation.
     */
    public interface FloatKeyframes extends Keyframes {

        /**
         * Works like {@link #getValue(float)}, but returning a primitive.
         * @param fraction The elapsed fraction of the animation
         * @return The animated value.
         */
        float getFloatValue(float fraction);
    }
}
Loading