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 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() { 50d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar final List<Keyframe> keyframes = mKeyframes; 51d422dc358f0100106dc07d7b903201eb9b043b11Yigit Boyar final 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 608619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar @Override 61984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public void invalidateCache() { 628619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar firstTime = true; 638619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar } 648619f48fb353740f7fd3f6eaa86fe493377e6cadYigit Boyar 65984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 667c608f25d494c8a0a671e7373efbb47ca635367eChet Haase public float getFloatValue(float fraction) { 677c608f25d494c8a0a671e7373efbb47ca635367eChet Haase if (mNumKeyframes == 2) { 687c608f25d494c8a0a671e7373efbb47ca635367eChet Haase if (firstTime) { 697c608f25d494c8a0a671e7373efbb47ca635367eChet Haase firstTime = false; 707c608f25d494c8a0a671e7373efbb47ca635367eChet Haase firstValue = ((FloatKeyframe) mKeyframes.get(0)).getFloatValue(); 717c608f25d494c8a0a671e7373efbb47ca635367eChet Haase lastValue = ((FloatKeyframe) mKeyframes.get(1)).getFloatValue(); 727c608f25d494c8a0a671e7373efbb47ca635367eChet Haase deltaValue = lastValue - firstValue; 737c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 747c608f25d494c8a0a671e7373efbb47ca635367eChet Haase if (mInterpolator != null) { 757c608f25d494c8a0a671e7373efbb47ca635367eChet Haase fraction = mInterpolator.getInterpolation(fraction); 767c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 777c608f25d494c8a0a671e7373efbb47ca635367eChet Haase if (mEvaluator == null) { 787c608f25d494c8a0a671e7373efbb47ca635367eChet Haase return firstValue + fraction * deltaValue; 797c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } else { 807c608f25d494c8a0a671e7373efbb47ca635367eChet Haase return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).floatValue(); 817c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 827c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 837c608f25d494c8a0a671e7373efbb47ca635367eChet Haase if (fraction <= 0f) { 847c608f25d494c8a0a671e7373efbb47ca635367eChet Haase final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0); 857c608f25d494c8a0a671e7373efbb47ca635367eChet Haase final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1); 867c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float prevValue = prevKeyframe.getFloatValue(); 877c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float nextValue = nextKeyframe.getFloatValue(); 887c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float prevFraction = prevKeyframe.getFraction(); 897c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float nextFraction = nextKeyframe.getFraction(); 907c608f25d494c8a0a671e7373efbb47ca635367eChet Haase final TimeInterpolator interpolator = nextKeyframe.getInterpolator(); 917c608f25d494c8a0a671e7373efbb47ca635367eChet Haase if (interpolator != null) { 927c608f25d494c8a0a671e7373efbb47ca635367eChet Haase fraction = interpolator.getInterpolation(fraction); 937c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 947c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); 957c608f25d494c8a0a671e7373efbb47ca635367eChet Haase return mEvaluator == null ? 96750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase prevValue + intervalFraction * (nextValue - prevValue) : 977c608f25d494c8a0a671e7373efbb47ca635367eChet Haase ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). 987c608f25d494c8a0a671e7373efbb47ca635367eChet Haase floatValue(); 997c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } else if (fraction >= 1f) { 1007c608f25d494c8a0a671e7373efbb47ca635367eChet Haase final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2); 1017c608f25d494c8a0a671e7373efbb47ca635367eChet Haase final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1); 1027c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float prevValue = prevKeyframe.getFloatValue(); 1037c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float nextValue = nextKeyframe.getFloatValue(); 1047c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float prevFraction = prevKeyframe.getFraction(); 1057c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float nextFraction = nextKeyframe.getFraction(); 1067c608f25d494c8a0a671e7373efbb47ca635367eChet Haase final TimeInterpolator interpolator = nextKeyframe.getInterpolator(); 1077c608f25d494c8a0a671e7373efbb47ca635367eChet Haase if (interpolator != null) { 1087c608f25d494c8a0a671e7373efbb47ca635367eChet Haase fraction = interpolator.getInterpolation(fraction); 1097c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 1107c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction); 1117c608f25d494c8a0a671e7373efbb47ca635367eChet Haase return mEvaluator == null ? 112750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase prevValue + intervalFraction * (nextValue - prevValue) : 1137c608f25d494c8a0a671e7373efbb47ca635367eChet Haase ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). 1147c608f25d494c8a0a671e7373efbb47ca635367eChet Haase floatValue(); 1157c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 1167c608f25d494c8a0a671e7373efbb47ca635367eChet Haase FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0); 1177c608f25d494c8a0a671e7373efbb47ca635367eChet Haase for (int i = 1; i < mNumKeyframes; ++i) { 1187c608f25d494c8a0a671e7373efbb47ca635367eChet Haase FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i); 1197c608f25d494c8a0a671e7373efbb47ca635367eChet Haase if (fraction < nextKeyframe.getFraction()) { 1207c608f25d494c8a0a671e7373efbb47ca635367eChet Haase final TimeInterpolator interpolator = nextKeyframe.getInterpolator(); 1217c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float intervalFraction = (fraction - prevKeyframe.getFraction()) / 1227c608f25d494c8a0a671e7373efbb47ca635367eChet Haase (nextKeyframe.getFraction() - prevKeyframe.getFraction()); 1237c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float prevValue = prevKeyframe.getFloatValue(); 1247c608f25d494c8a0a671e7373efbb47ca635367eChet Haase float nextValue = nextKeyframe.getFloatValue(); 1256df99053ebd6d32ed1c0e83516b480a6843770c3Doris Liu // Apply interpolator on the proportional duration. 1266df99053ebd6d32ed1c0e83516b480a6843770c3Doris Liu if (interpolator != null) { 1276df99053ebd6d32ed1c0e83516b480a6843770c3Doris Liu intervalFraction = interpolator.getInterpolation(intervalFraction); 1286df99053ebd6d32ed1c0e83516b480a6843770c3Doris Liu } 1297c608f25d494c8a0a671e7373efbb47ca635367eChet Haase return mEvaluator == null ? 130750e12e18f7ce9654cadf11b9e933afb29b59311Chet Haase prevValue + intervalFraction * (nextValue - prevValue) : 1317c608f25d494c8a0a671e7373efbb47ca635367eChet Haase ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)). 1327c608f25d494c8a0a671e7373efbb47ca635367eChet Haase floatValue(); 1337c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 1347c608f25d494c8a0a671e7373efbb47ca635367eChet Haase prevKeyframe = nextKeyframe; 1357c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 1367c608f25d494c8a0a671e7373efbb47ca635367eChet Haase // shouldn't get here 1377c608f25d494c8a0a671e7373efbb47ca635367eChet Haase return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue(); 1387c608f25d494c8a0a671e7373efbb47ca635367eChet Haase } 1397c608f25d494c8a0a671e7373efbb47ca635367eChet Haase 140984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount @Override 141984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount public Class getType() { 142984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount return Float.class; 143984011f6850fd4b6ad4db6d6022bd475d7a2c712George Mount } 1447c608f25d494c8a0a671e7373efbb47ca635367eChet Haase} 1457c608f25d494c8a0a671e7373efbb47ca635367eChet Haase 146