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.IntKeyframe;
20
21import java.util.List;
22
23/**
24 * This class holds a collection of IntKeyframe 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 * float, 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 IntKeyframeSet extends KeyframeSet implements Keyframes.IntKeyframes {
34    public IntKeyframeSet(IntKeyframe... keyframes) {
35        super(keyframes);
36    }
37
38    @Override
39    public Object getValue(float fraction) {
40        return getIntValue(fraction);
41    }
42
43    @Override
44    public IntKeyframeSet clone() {
45        List<Keyframe> keyframes = mKeyframes;
46        int numKeyframes = mKeyframes.size();
47        IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes];
48        for (int i = 0; i < numKeyframes; ++i) {
49            newKeyframes[i] = (IntKeyframe) keyframes.get(i).clone();
50        }
51        IntKeyframeSet newSet = new IntKeyframeSet(newKeyframes);
52        return newSet;
53    }
54
55    @Override
56    public int getIntValue(float fraction) {
57        if (fraction <= 0f) {
58            final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
59            final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(1);
60            int prevValue = prevKeyframe.getIntValue();
61            int nextValue = nextKeyframe.getIntValue();
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 + (int)(intervalFraction * (nextValue - prevValue)) :
71                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
72                            intValue();
73        } else if (fraction >= 1f) {
74            final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 2);
75            final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 1);
76            int prevValue = prevKeyframe.getIntValue();
77            int nextValue = nextKeyframe.getIntValue();
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 + (int)(intervalFraction * (nextValue - prevValue)) :
87                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue();
88        }
89        IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
90        for (int i = 1; i < mNumKeyframes; ++i) {
91            IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(i);
92            if (fraction < nextKeyframe.getFraction()) {
93                final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
94                float intervalFraction = (fraction - prevKeyframe.getFraction()) /
95                    (nextKeyframe.getFraction() - prevKeyframe.getFraction());
96                int prevValue = prevKeyframe.getIntValue();
97                int nextValue = nextKeyframe.getIntValue();
98                // Apply interpolator on the proportional duration.
99                if (interpolator != null) {
100                    intervalFraction = interpolator.getInterpolation(intervalFraction);
101                }
102                return mEvaluator == null ?
103                        prevValue + (int)(intervalFraction * (nextValue - prevValue)) :
104                        ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
105                                intValue();
106            }
107            prevKeyframe = nextKeyframe;
108        }
109        // shouldn't get here
110        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue();
111    }
112
113    @Override
114    public Class getType() {
115        return Integer.class;
116    }
117}
118
119