FileDocCategorySizeDatePackage
KeyframeSet.javaAPI DocAndroid 5.1 API10726Thu Mar 12 22:22:08 GMT 2015android.animation

KeyframeSet

public class KeyframeSet extends Object implements Keyframes
This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate 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.

Fields Summary
int
mNumKeyframes
Keyframe
mFirstKeyframe
Keyframe
mLastKeyframe
TimeInterpolator
mInterpolator
List
mKeyframes
TypeEvaluator
mEvaluator
Constructors Summary
public KeyframeSet(Keyframe keyframes)

        mNumKeyframes = keyframes.length;
        // immutable list
        mKeyframes = Arrays.asList(keyframes);
        mFirstKeyframe = keyframes[0];
        mLastKeyframe = keyframes[mNumKeyframes - 1];
        mInterpolator = mLastKeyframe.getInterpolator();
    
Methods Summary
public android.animation.KeyframeSetclone()

        List<Keyframe> keyframes = mKeyframes;
        int numKeyframes = mKeyframes.size();
        final Keyframe[] newKeyframes = new Keyframe[numKeyframes];
        for (int i = 0; i < numKeyframes; ++i) {
            newKeyframes[i] = keyframes.get(i).clone();
        }
        KeyframeSet newSet = new KeyframeSet(newKeyframes);
        return newSet;
    
public java.util.ListgetKeyframes()

        return mKeyframes;
    
public java.lang.ClassgetType()

        return mFirstKeyframe.getType();
    
public java.lang.ObjectgetValue(float fraction)
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.


        // Special-case optimization for the common case of only two keyframes
        if (mNumKeyframes == 2) {
            if (mInterpolator != null) {
                fraction = mInterpolator.getInterpolation(fraction);
            }
            return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(),
                    mLastKeyframe.getValue());
        }
        if (fraction <= 0f) {
            final Keyframe nextKeyframe = mKeyframes.get(1);
            final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
            if (interpolator != null) {
                fraction = interpolator.getInterpolation(fraction);
            }
            final float prevFraction = mFirstKeyframe.getFraction();
            float intervalFraction = (fraction - prevFraction) /
                (nextKeyframe.getFraction() - prevFraction);
            return mEvaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(),
                    nextKeyframe.getValue());
        } else if (fraction >= 1f) {
            final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2);
            final TimeInterpolator interpolator = mLastKeyframe.getInterpolator();
            if (interpolator != null) {
                fraction = interpolator.getInterpolation(fraction);
            }
            final float prevFraction = prevKeyframe.getFraction();
            float intervalFraction = (fraction - prevFraction) /
                (mLastKeyframe.getFraction() - prevFraction);
            return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
                    mLastKeyframe.getValue());
        }
        Keyframe prevKeyframe = mFirstKeyframe;
        for (int i = 1; i < mNumKeyframes; ++i) {
            Keyframe nextKeyframe = mKeyframes.get(i);
            if (fraction < nextKeyframe.getFraction()) {
                final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
                if (interpolator != null) {
                    fraction = interpolator.getInterpolation(fraction);
                }
                final float prevFraction = prevKeyframe.getFraction();
                float intervalFraction = (fraction - prevFraction) /
                    (nextKeyframe.getFraction() - prevFraction);
                return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
                        nextKeyframe.getValue());
            }
            prevKeyframe = nextKeyframe;
        }
        // shouldn't reach here
        return mLastKeyframe.getValue();
    
public voidinvalidateCache()
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.

    
public static android.animation.KeyframeSetofFloat(float values)

        boolean badValue = false;
        int numKeyframes = values.length;
        FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];
        if (numKeyframes == 1) {
            keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);
            keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);
            if (Float.isNaN(values[0])) {
                badValue = true;
            }
        } else {
            keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);
            for (int i = 1; i < numKeyframes; ++i) {
                keyframes[i] =
                        (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);
                if (Float.isNaN(values[i])) {
                    badValue = true;
                }
            }
        }
        if (badValue) {
            Log.w("Animator", "Bad value (NaN) in float animator");
        }
        return new FloatKeyframeSet(keyframes);
    
public static android.animation.KeyframeSetofInt(int values)

        int numKeyframes = values.length;
        IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)];
        if (numKeyframes == 1) {
            keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f);
            keyframes[1] = (IntKeyframe) Keyframe.ofInt(1f, values[0]);
        } else {
            keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f, values[0]);
            for (int i = 1; i < numKeyframes; ++i) {
                keyframes[i] =
                        (IntKeyframe) Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]);
            }
        }
        return new IntKeyframeSet(keyframes);
    
public static android.animation.KeyframeSetofKeyframe(Keyframe keyframes)

        // if all keyframes of same primitive type, create the appropriate KeyframeSet
        int numKeyframes = keyframes.length;
        boolean hasFloat = false;
        boolean hasInt = false;
        boolean hasOther = false;
        for (int i = 0; i < numKeyframes; ++i) {
            if (keyframes[i] instanceof FloatKeyframe) {
                hasFloat = true;
            } else if (keyframes[i] instanceof IntKeyframe) {
                hasInt = true;
            } else {
                hasOther = true;
            }
        }
        if (hasFloat && !hasInt && !hasOther) {
            FloatKeyframe floatKeyframes[] = new FloatKeyframe[numKeyframes];
            for (int i = 0; i < numKeyframes; ++i) {
                floatKeyframes[i] = (FloatKeyframe) keyframes[i];
            }
            return new FloatKeyframeSet(floatKeyframes);
        } else if (hasInt && !hasFloat && !hasOther) {
            IntKeyframe intKeyframes[] = new IntKeyframe[numKeyframes];
            for (int i = 0; i < numKeyframes; ++i) {
                intKeyframes[i] = (IntKeyframe) keyframes[i];
            }
            return new IntKeyframeSet(intKeyframes);
        } else {
            return new KeyframeSet(keyframes);
        }
    
public static android.animation.KeyframeSetofObject(java.lang.Object values)

        int numKeyframes = values.length;
        ObjectKeyframe keyframes[] = new ObjectKeyframe[Math.max(numKeyframes,2)];
        if (numKeyframes == 1) {
            keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f);
            keyframes[1] = (ObjectKeyframe) Keyframe.ofObject(1f, values[0]);
        } else {
            keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f, values[0]);
            for (int i = 1; i < numKeyframes; ++i) {
                keyframes[i] = (ObjectKeyframe) Keyframe.ofObject((float) i / (numKeyframes - 1), values[i]);
            }
        }
        return new KeyframeSet(keyframes);
    
public static PathKeyframesofPath(android.graphics.Path path)

        return new PathKeyframes(path);
    
public static PathKeyframesofPath(android.graphics.Path path, float error)

        return new PathKeyframes(path, error);
    
public voidsetEvaluator(TypeEvaluator evaluator)
Sets the TypeEvaluator to be used when calculating animated values. This object is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet, 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.

        mEvaluator = evaluator;
    
public java.lang.StringtoString()

        String returnVal = " ";
        for (int i = 0; i < mNumKeyframes; ++i) {
            returnVal += mKeyframes.get(i).getValue() + "  ";
        }
        return returnVal;