1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.animation;
18
19import android.animation.Keyframe.FloatKeyframe;
20
21import java.util.List;
22
23/**
24 * This class holds a collection of FloatKeyframe objects and is called by ValueAnimator to calculate
25 * values between those keyframes for a given animation. The class internal to the animation
26 * package because it is an implementation detail of how Keyframes are stored and used.
27 *
28 * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclass for
29 * int, exists to speed up the getValue() method when there is no custom
30 * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
31 * Object equivalents of these primitive types.</p>
32 */
33class FloatKeyframeSet extends KeyframeSet implements Keyframes.FloatKeyframes {
34    public FloatKeyframeSet(FloatKeyframe... keyframes) {
35        super(keyframes);
36    }
37
38    @Override
39    public Object getValue(float fraction) {
40        return getFloatValue(fraction);
41    }
42
43    @Override
44    public FloatKeyframeSet clone() {
45        final List<Keyframe> keyframes = mKeyframes;
46        final int numKeyframes = mKeyframes.size();
47        FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes];
48        for (int i = 0; i < numKeyframes; ++i) {
49            newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone();
50        }
51        FloatKeyframeSet newSet = new FloatKeyframeSet(newKeyframes);
52        return newSet;
53    }
54
55    @Override
56    public float getFloatValue(float fraction) {
57        if (fraction <= 0f) {
58            final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
59            final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1);
60            float prevValue = prevKeyframe.getFloatValue();
61            float nextValue = nextKeyframe.getFloatValue();
62            float prevFraction = prevKeyframe.getFraction();
63            float nextFraction = nextKeyframe.getFraction();
64            final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
65            if (interpolator != null) {
66                fraction = interpolator.getInterpolation(fraction);
67            }
68            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
69            return mEvaluator == null ?
70                    prevValue + intervalFraction * (nextValue - prevValue) :
71                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
72                            floatValue();
73        } else if (fraction >= 1f) {
74            final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2);
75            final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1);
76            float prevValue = prevKeyframe.getFloatValue();
77            float nextValue = nextKeyframe.getFloatValue();
78            float prevFraction = prevKeyframe.getFraction();
79            float nextFraction = nextKeyframe.getFraction();
80            final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
81            if (interpolator != null) {
82                fraction = interpolator.getInterpolation(fraction);
83            }
84            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
85            return mEvaluator == null ?
86                    prevValue + intervalFraction * (nextValue - prevValue) :
87                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
88                            floatValue();
89        }
90        FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
91        for (int i = 1; i < mNumKeyframes; ++i) {
92            FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i);
93            if (fraction < nextKeyframe.getFraction()) {
94                final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
95                float intervalFraction = (fraction - prevKeyframe.getFraction()) /
96                    (nextKeyframe.getFraction() - prevKeyframe.getFraction());
97                float prevValue = prevKeyframe.getFloatValue();
98                float nextValue = nextKeyframe.getFloatValue();
99                // Apply interpolator on the proportional duration.
100                if (interpolator != null) {
101                    intervalFraction = interpolator.getInterpolation(intervalFraction);
102                }
103                return mEvaluator == null ?
104                        prevValue + intervalFraction * (nextValue - prevValue) :
105                        ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
106                            floatValue();
107            }
108            prevKeyframe = nextKeyframe;
109        }
110        // shouldn't get here
111        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
112    }
113
114    @Override
115    public Class getType() {
116        return Float.class;
117    }
118}
119
120