FlingAnimationUtils.java revision efbd7e3bb8244efae2561f0d9d7cedb36b1730bd
187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi/* 287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * Copyright (C) 2014 The Android Open Source Project 387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * 487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * you may not use this file except in compliance with the License. 687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * You may obtain a copy of the License at 787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * 887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * 1087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * Unless required by applicable law or agreed to in writing, software 1187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 1287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * See the License for the specific language governing permissions and 1487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * limitations under the License 1587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi */ 1687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 1787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggipackage com.android.systemui.statusbar; 1887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 1987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggiimport android.animation.ValueAnimator; 2087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggiimport android.content.Context; 2187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggiimport android.view.animation.AnimationUtils; 2287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggiimport android.view.animation.Interpolator; 2387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggiimport android.view.animation.PathInterpolator; 2487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 2587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi/** 2687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * Utility class to calculate general fling animation when the finger is released. 2787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi */ 2887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggipublic class FlingAnimationUtils { 2987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 301d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi private static final float LINEAR_OUT_SLOW_IN_X2 = 0.35f; 31efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi private static final float LINEAR_OUT_FASTER_IN_Y2_MIN = 0.7f; 32efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi private static final float LINEAR_OUT_FASTER_IN_Y2_MAX = 1f; 3387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private static final float MIN_VELOCITY_DP_PER_SECOND = 250; 34efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi private static final float HIGH_VELOCITY_DP_PER_SECOND = 3000; 3587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 3687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi /** 3787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * Crazy math. http://en.wikipedia.org/wiki/B%C3%A9zier_curve 3887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi */ 391d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi private static final float LINEAR_OUT_SLOW_IN_START_GRADIENT = 1.0f / LINEAR_OUT_SLOW_IN_X2; 4087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 4187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private Interpolator mLinearOutSlowIn; 4287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private Interpolator mFastOutSlowIn; 431d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi private Interpolator mFastOutLinearIn; 441d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi 4587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private float mMinVelocityPxPerSecond; 461d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi private float mMaxLengthSeconds; 47efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi private float mHighVelocityPxPerSecond; 4887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 491d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi public FlingAnimationUtils(Context ctx, float maxLengthSeconds) { 501d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi mMaxLengthSeconds = maxLengthSeconds; 511d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi mLinearOutSlowIn = new PathInterpolator(0, 0, LINEAR_OUT_SLOW_IN_X2, 1); 5287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi mFastOutSlowIn 5387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.fast_out_slow_in); 541d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi mFastOutLinearIn 551d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.fast_out_linear_in); 5687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi mMinVelocityPxPerSecond 5787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi = MIN_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density; 58efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi mHighVelocityPxPerSecond 59efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi = HIGH_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density; 6087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } 6187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 6287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi /** 6387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * Applies the interpolator and length to the animator, such that the fling animation is 6487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * consistent with the finger motion. 6587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * 6687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * @param animator the animator to apply 6787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * @param currValue the current value 6887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * @param endValue the end value of the animator 6987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * @param velocity the current velocity of the motion 7087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi */ 7187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi public void apply(ValueAnimator animator, float currValue, float endValue, float velocity) { 721d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue)); 731d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi } 741d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi 751d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi /** 761d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * Applies the interpolator and length to the animator, such that the fling animation is 771d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * consistent with the finger motion. 781d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * 791d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param animator the animator to apply 801d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param currValue the current value 811d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param endValue the end value of the animator 821d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param velocity the current velocity of the motion 831d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param maxDistance the maximum distance for this interaction; the maximum animation length 841d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * gets multiplied by the ratio between the actual distance and this value 851d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi */ 861d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi public void apply(ValueAnimator animator, float currValue, float endValue, float velocity, 871d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi float maxDistance) { 881d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi float maxLengthSeconds = (float) (mMaxLengthSeconds 891d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * Math.sqrt(Math.abs(endValue - currValue) / maxDistance)); 9087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi float diff = Math.abs(endValue - currValue); 9187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi float velAbs = Math.abs(velocity); 9287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi float durationSeconds = LINEAR_OUT_SLOW_IN_START_GRADIENT * diff / velAbs; 931d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi if (durationSeconds <= maxLengthSeconds) { 9487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi animator.setInterpolator(mLinearOutSlowIn); 9587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } else if (velAbs >= mMinVelocityPxPerSecond) { 9687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 9787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi // Cross fade between fast-out-slow-in and linear interpolator with current velocity. 981d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi durationSeconds = maxLengthSeconds; 9987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi VelocityInterpolator velocityInterpolator 10087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi = new VelocityInterpolator(durationSeconds, velAbs, diff); 10187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator( 10287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi velocityInterpolator, mLinearOutSlowIn, mLinearOutSlowIn); 10387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi animator.setInterpolator(superInterpolator); 10487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } else { 10587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 10687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi // Just use a normal interpolator which doesn't take the velocity into account. 1071d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi durationSeconds = maxLengthSeconds; 10887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi animator.setInterpolator(mFastOutSlowIn); 10987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } 11087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi animator.setDuration((long) (durationSeconds * 1000)); 11187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } 11287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 11387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi /** 1141d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * Applies the interpolator and length to the animator, such that the fling animation is 1151d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * consistent with the finger motion for the case when the animation is making something 1161d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * disappear. 1171d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * 1181d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param animator the animator to apply 1191d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param currValue the current value 1201d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param endValue the end value of the animator 1211d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param velocity the current velocity of the motion 1221d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @param maxDistance the maximum distance for this interaction; the maximum animation length 1231d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * gets multiplied by the ratio between the actual distance and this value 1241d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi */ 1251d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi public void applyDismissing(ValueAnimator animator, float currValue, float endValue, 1261d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi float velocity, float maxDistance) { 1271d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi float maxLengthSeconds = (float) (mMaxLengthSeconds 1281d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * Math.pow(Math.abs(endValue - currValue) / maxDistance, 0.5f)); 1291d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi float diff = Math.abs(endValue - currValue); 1301d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi float velAbs = Math.abs(velocity); 131efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi float y2 = calculateLinearOutFasterInY2(velAbs); 132efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi 133efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi // The gradient at the start of the curve is just y2. 134efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi float startGradient = y2; 135efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi Interpolator mLinearOutFasterIn = new PathInterpolator(0, 0, 1, y2); 136efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi float durationSeconds = startGradient * diff / velAbs; 1371d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi if (durationSeconds <= maxLengthSeconds) { 1381d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi animator.setInterpolator(mLinearOutFasterIn); 1391d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi } else if (velAbs >= mMinVelocityPxPerSecond) { 1401d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi 1411d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi // Cross fade between linear-out-faster-in and linear interpolator with current 1421d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi // velocity. 1431d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi durationSeconds = maxLengthSeconds; 1441d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi VelocityInterpolator velocityInterpolator 1451d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi = new VelocityInterpolator(durationSeconds, velAbs, diff); 1461d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator( 1471d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi velocityInterpolator, mLinearOutFasterIn, mLinearOutSlowIn); 1481d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi animator.setInterpolator(superInterpolator); 1491d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi } else { 1501d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi 1511d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi // Just use a normal interpolator which doesn't take the velocity into account. 1521d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi durationSeconds = maxLengthSeconds; 1531d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi animator.setInterpolator(mFastOutLinearIn); 1541d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi } 1551d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi animator.setDuration((long) (durationSeconds * 1000)); 1561d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi } 1571d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi 1581d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi /** 159efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi * Calculates the y2 control point for a linear-out-faster-in path interpolator depending on the 160efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi * velocity. The faster the velocity, the more "linear" the interpolator gets. 161efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi * 162efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi * @param velocity the velocity of the gesture. 163efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi * @return the y2 control point for a cubic bezier path interpolator 164efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi */ 165efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi private float calculateLinearOutFasterInY2(float velocity) { 166efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi float t = (velocity - mMinVelocityPxPerSecond) 167efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi / (mHighVelocityPxPerSecond - mMinVelocityPxPerSecond); 168efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi t = Math.max(0, Math.min(1, t)); 169efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi return (1 - t) * LINEAR_OUT_FASTER_IN_Y2_MIN + t * LINEAR_OUT_FASTER_IN_Y2_MAX; 170efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi } 171efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi 172efbd7e3bb8244efae2561f0d9d7cedb36b1730bdJorim Jaggi /** 1731d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi * @return the minimum velocity a gesture needs to have to be considered a fling 1741d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi */ 1751d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi public float getMinVelocityPxPerSecond() { 1761d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi return mMinVelocityPxPerSecond; 1771d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi } 1781d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi 1791d480695df31f1c328473f32d5007cea6a03b6e0Jorim Jaggi /** 18087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * An interpolator which interpolates two interpolators with an interpolator. 18187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi */ 18287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private static final class InterpolatorInterpolator implements Interpolator { 18387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 18487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private Interpolator mInterpolator1; 18587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private Interpolator mInterpolator2; 18687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private Interpolator mCrossfader; 18787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 18887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi InterpolatorInterpolator(Interpolator interpolator1, Interpolator interpolator2, 18987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi Interpolator crossfader) { 19087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi mInterpolator1 = interpolator1; 19187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi mInterpolator2 = interpolator2; 19287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi mCrossfader = crossfader; 19387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } 19487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 19587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi @Override 19687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi public float getInterpolation(float input) { 19787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi float t = mCrossfader.getInterpolation(input); 19887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi return (1 - t) * mInterpolator1.getInterpolation(input) 19987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi + t * mInterpolator2.getInterpolation(input); 20087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } 20187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } 20287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 20387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi /** 20487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi * An interpolator which interpolates with a fixed velocity. 20587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi */ 20687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private static final class VelocityInterpolator implements Interpolator { 20787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 20887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private float mDurationSeconds; 20987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private float mVelocity; 21087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private float mDiff; 21187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 21287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi private VelocityInterpolator(float durationSeconds, float velocity, float diff) { 21387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi mDurationSeconds = durationSeconds; 21487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi mVelocity = velocity; 21587cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi mDiff = diff; 21687cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } 21787cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi 21887cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi @Override 21987cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi public float getInterpolation(float input) { 22087cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi float time = input * mDurationSeconds; 22187cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi return time * mVelocity / mDiff; 22287cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } 22387cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi } 22487cd5e71ec087e191b8baaa8913a878f92d4e10dJorim Jaggi} 225