17c608f25d494c8a0a671e7373efbb47ca635367eChet Haase/*
27c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * Copyright (C) 2010 The Android Open Source Project
37c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *
47c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * Licensed under the Apache License, Version 2.0 (the "License");
57c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * you may not use this file except in compliance with the License.
67c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * You may obtain a copy of the License at
77c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *
87c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *      http://www.apache.org/licenses/LICENSE-2.0
97c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *
107c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * Unless required by applicable law or agreed to in writing, software
117c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * distributed under the License is distributed on an "AS IS" BASIS,
127c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * See the License for the specific language governing permissions and
147c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * limitations under the License.
157c608f25d494c8a0a671e7373efbb47ca635367eChet Haase */
167c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
177c608f25d494c8a0a671e7373efbb47ca635367eChet Haasepackage android.animation;
187c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
197c608f25d494c8a0a671e7373efbb47ca635367eChet Haaseimport android.animation.Keyframe.FloatKeyframe;
207c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
217c608f25d494c8a0a671e7373efbb47ca635367eChet Haaseimport java.util.ArrayList;
227c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
237c608f25d494c8a0a671e7373efbb47ca635367eChet Haase/**
247c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * This class holds a collection of FloatKeyframe objects and is called by ValueAnimator to calculate
257c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * values between those keyframes for a given animation. The class internal to the animation
267c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * package because it is an implementation detail of how Keyframes are stored and used.
277c608f25d494c8a0a671e7373efbb47ca635367eChet Haase *
28b2ab04ffb6894f399d5c9ceb15f64eb17b654426Chet Haase * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclass for
29b2ab04ffb6894f399d5c9ceb15f64eb17b654426Chet Haase * int, exists to speed up the getValue() method when there is no custom
307c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
317c608f25d494c8a0a671e7373efbb47ca635367eChet Haase * Object equivalents of these primitive types.</p>
327c608f25d494c8a0a671e7373efbb47ca635367eChet Haase */
337c608f25d494c8a0a671e7373efbb47ca635367eChet Haaseclass FloatKeyframeSet extends KeyframeSet {
347c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    private float firstValue;
357c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    private float lastValue;
367c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    private float deltaValue;
377c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    private boolean firstTime = true;
387c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
397c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public FloatKeyframeSet(FloatKeyframe... keyframes) {
407c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        super(keyframes);
417c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
427c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
437c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    @Override
447c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public Object getValue(float fraction) {
457c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        return getFloatValue(fraction);
467c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
477c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
487c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    @Override
497c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public FloatKeyframeSet clone() {
507c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        ArrayList<Keyframe> keyframes = mKeyframes;
517c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        int numKeyframes = mKeyframes.size();
527c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes];
537c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        for (int i = 0; i < numKeyframes; ++i) {
547c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone();
557c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
567c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        FloatKeyframeSet newSet = new FloatKeyframeSet(newKeyframes);
577c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        return newSet;
587c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
597c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
607c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public float getFloatValue(float fraction) {
617c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        if (mNumKeyframes == 2) {
627c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (firstTime) {
637c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                firstTime = false;
647c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                firstValue = ((FloatKeyframe) mKeyframes.get(0)).getFloatValue();
657c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                lastValue = ((FloatKeyframe) mKeyframes.get(1)).getFloatValue();
667c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                deltaValue = lastValue - firstValue;
677c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
687c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (mInterpolator != null) {
697c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                fraction = mInterpolator.getInterpolation(fraction);
707c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
717c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (mEvaluator == null) {
727c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                return firstValue + fraction * deltaValue;
737c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            } else {
747c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).floatValue();
757c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
767c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
777c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        if (fraction <= 0f) {
787c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
797c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1);
807c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevValue = prevKeyframe.getFloatValue();
817c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextValue = nextKeyframe.getFloatValue();
827c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevFraction = prevKeyframe.getFraction();
837c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextFraction = nextKeyframe.getFraction();
847c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
857c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (interpolator != null) {
867c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                fraction = interpolator.getInterpolation(fraction);
877c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
887c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
897c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            return mEvaluator == null ?
90750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase                    prevValue + intervalFraction * (nextValue - prevValue) :
917c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
927c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                            floatValue();
937c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        } else if (fraction >= 1f) {
947c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2);
957c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1);
967c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevValue = prevKeyframe.getFloatValue();
977c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextValue = nextKeyframe.getFloatValue();
987c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevFraction = prevKeyframe.getFraction();
997c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextFraction = nextKeyframe.getFraction();
1007c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
1017c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (interpolator != null) {
1027c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                fraction = interpolator.getInterpolation(fraction);
1037c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
1047c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
1057c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            return mEvaluator == null ?
106750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase                    prevValue + intervalFraction * (nextValue - prevValue) :
1077c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
1087c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                            floatValue();
1097c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
1107c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
1117c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        for (int i = 1; i < mNumKeyframes; ++i) {
1127c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i);
1137c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (fraction < nextKeyframe.getFraction()) {
1147c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
1157c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                if (interpolator != null) {
1167c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    fraction = interpolator.getInterpolation(fraction);
1177c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                }
1187c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                float intervalFraction = (fraction - prevKeyframe.getFraction()) /
1197c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    (nextKeyframe.getFraction() - prevKeyframe.getFraction());
1207c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                float prevValue = prevKeyframe.getFloatValue();
1217c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                float nextValue = nextKeyframe.getFloatValue();
1227c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                return mEvaluator == null ?
123750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase                        prevValue + intervalFraction * (nextValue - prevValue) :
1247c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                        ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
1257c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                            floatValue();
1267c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
1277c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            prevKeyframe = nextKeyframe;
1287c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
1297c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        // shouldn't get here
1307c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
1317c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
1327c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
1337c608f25d494c8a0a671e7373efbb47ca635367eChet Haase}
1347c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
135