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
21d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyarimport java.util.List;
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 */
33984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mountclass FloatKeyframeSet extends KeyframeSet implements Keyframes.FloatKeyframes {
347c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public FloatKeyframeSet(FloatKeyframe... keyframes) {
357c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        super(keyframes);
367c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
377c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
387c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    @Override
397c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public Object getValue(float fraction) {
407c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        return getFloatValue(fraction);
417c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
427c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
437c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    @Override
447c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public FloatKeyframeSet clone() {
45d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        final List<Keyframe> keyframes = mKeyframes;
46d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar        final int numKeyframes = mKeyframes.size();
477c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes];
487c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        for (int i = 0; i < numKeyframes; ++i) {
497c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone();
507c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
517c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        FloatKeyframeSet newSet = new FloatKeyframeSet(newKeyframes);
527c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        return newSet;
537c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
547c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
558619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar    @Override
567c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    public float getFloatValue(float fraction) {
577c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        if (fraction <= 0f) {
587c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
597c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1);
607c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevValue = prevKeyframe.getFloatValue();
617c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextValue = nextKeyframe.getFloatValue();
627c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevFraction = prevKeyframe.getFraction();
637c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextFraction = nextKeyframe.getFraction();
647c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
657c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (interpolator != null) {
667c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                fraction = interpolator.getInterpolation(fraction);
677c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
687c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
697c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            return mEvaluator == null ?
70750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase                    prevValue + intervalFraction * (nextValue - prevValue) :
717c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
727c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                            floatValue();
737c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        } else if (fraction >= 1f) {
747c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2);
757c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1);
767c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevValue = prevKeyframe.getFloatValue();
777c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextValue = nextKeyframe.getFloatValue();
787c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float prevFraction = prevKeyframe.getFraction();
797c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float nextFraction = nextKeyframe.getFraction();
807c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
817c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (interpolator != null) {
827c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                fraction = interpolator.getInterpolation(fraction);
837c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
847c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
857c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            return mEvaluator == null ?
86750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase                    prevValue + intervalFraction * (nextValue - prevValue) :
877c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
887c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                            floatValue();
897c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
907c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
917c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        for (int i = 1; i < mNumKeyframes; ++i) {
927c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i);
937c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            if (fraction < nextKeyframe.getFraction()) {
947c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
957c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                float intervalFraction = (fraction - prevKeyframe.getFraction()) /
967c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                    (nextKeyframe.getFraction() - prevKeyframe.getFraction());
977c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                float prevValue = prevKeyframe.getFloatValue();
987c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                float nextValue = nextKeyframe.getFloatValue();
996df99053ebd6d32ed1c0e83516b480a6843770c3Doris Liu                // Apply interpolator on the proportional duration.
1006df99053ebd6d32ed1c0e83516b480a6843770c3Doris Liu                if (interpolator != null) {
1016df99053ebd6d32ed1c0e83516b480a6843770c3Doris Liu                    intervalFraction = interpolator.getInterpolation(intervalFraction);
1026df99053ebd6d32ed1c0e83516b480a6843770c3Doris Liu                }
1037c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                return mEvaluator == null ?
104750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase                        prevValue + intervalFraction * (nextValue - prevValue) :
1057c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                        ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
1067c608f25d494c8a0a671e7373efbb47ca635367eChet Haase                            floatValue();
1077c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            }
1087c608f25d494c8a0a671e7373efbb47ca635367eChet Haase            prevKeyframe = nextKeyframe;
1097c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        }
1107c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        // shouldn't get here
1117c608f25d494c8a0a671e7373efbb47ca635367eChet Haase        return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
1127c608f25d494c8a0a671e7373efbb47ca635367eChet Haase    }
1137c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
114984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount    @Override
115984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount    public Class getType() {
116984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount        return Float.class;
117984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount    }
1187c608f25d494c8a0a671e7373efbb47ca635367eChet Haase}
1197c608f25d494c8a0a671e7373efbb47ca635367eChet Haase
120