ValueAnimatorCompatImplEclairMr1.java revision 631f64ec9c6255f38a7f746d7949b6a537c1180f
1/* 2 * Copyright (C) 2015 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.support.design.widget; 18 19import android.os.Handler; 20import android.os.Looper; 21import android.os.SystemClock; 22import android.view.animation.AccelerateDecelerateInterpolator; 23import android.view.animation.Interpolator; 24 25/** 26 * A 'fake' ValueAnimator implementation which uses a Runnable. 27 */ 28class ValueAnimatorCompatImplEclairMr1 extends ValueAnimatorCompat.Impl { 29 30 private static final int HANDLER_DELAY = 10; 31 private static final int DEFAULT_DURATION = 200; 32 33 private static final Handler sHandler = new Handler(Looper.getMainLooper()); 34 35 private long mStartTime; 36 private boolean mIsRunning; 37 38 private final int[] mIntValues = new int[2]; 39 private final float[] mFloatValues = new float[2]; 40 41 private int mDuration = DEFAULT_DURATION; 42 private Interpolator mInterpolator; 43 private AnimatorListenerProxy mListener; 44 private AnimatorUpdateListenerProxy mUpdateListener; 45 46 private float mAnimatedFraction; 47 48 @Override 49 public void start() { 50 if (mIsRunning) { 51 // If we're already running, ignore 52 return; 53 } 54 55 if (mInterpolator == null) { 56 mInterpolator = new AccelerateDecelerateInterpolator(); 57 } 58 59 mStartTime = SystemClock.uptimeMillis(); 60 mIsRunning = true; 61 62 if (mListener != null) { 63 mListener.onAnimationStart(); 64 } 65 66 sHandler.postDelayed(mRunnable, HANDLER_DELAY); 67 } 68 69 @Override 70 public boolean isRunning() { 71 return mIsRunning; 72 } 73 74 @Override 75 public void setInterpolator(Interpolator interpolator) { 76 mInterpolator = interpolator; 77 } 78 79 @Override 80 public void setListener(AnimatorListenerProxy listener) { 81 mListener = listener; 82 } 83 84 @Override 85 public void setUpdateListener(AnimatorUpdateListenerProxy updateListener) { 86 mUpdateListener = updateListener; 87 } 88 89 @Override 90 public void setIntValues(int from, int to) { 91 mIntValues[0] = from; 92 mIntValues[1] = to; 93 } 94 95 @Override 96 public int getAnimatedIntValue() { 97 return AnimationUtils.lerp(mIntValues[0], mIntValues[1], getAnimatedFraction()); 98 } 99 100 @Override 101 public void setFloatValues(float from, float to) { 102 mFloatValues[0] = from; 103 mFloatValues[1] = to; 104 } 105 106 @Override 107 public float getAnimatedFloatValue() { 108 return AnimationUtils.lerp(mFloatValues[0], mFloatValues[1], getAnimatedFraction()); 109 } 110 111 @Override 112 public void setDuration(int duration) { 113 mDuration = duration; 114 } 115 116 @Override 117 public void cancel() { 118 mIsRunning = false; 119 sHandler.removeCallbacks(mRunnable); 120 121 if (mListener != null) { 122 mListener.onAnimationCancel(); 123 } 124 } 125 126 @Override 127 public float getAnimatedFraction() { 128 return mAnimatedFraction; 129 } 130 131 @Override 132 public void end() { 133 if (mIsRunning) { 134 mIsRunning = false; 135 sHandler.removeCallbacks(mRunnable); 136 137 // Set our animated fraction to 1 138 mAnimatedFraction = 1f; 139 140 if (mUpdateListener != null) { 141 mUpdateListener.onAnimationUpdate(); 142 } 143 144 if (mListener != null) { 145 mListener.onAnimationEnd(); 146 } 147 } 148 } 149 150 private void update() { 151 if (mIsRunning) { 152 // Update the animated fraction 153 final long elapsed = SystemClock.uptimeMillis() - mStartTime; 154 final float linearFraction = elapsed / (float) mDuration; 155 mAnimatedFraction = mInterpolator != null 156 ? mInterpolator.getInterpolation(linearFraction) 157 : linearFraction; 158 159 // If we're running, dispatch tp the listener 160 if (mUpdateListener != null) { 161 mUpdateListener.onAnimationUpdate(); 162 } 163 164 // Check to see if we've passed the animation duration 165 if (SystemClock.uptimeMillis() >= (mStartTime + mDuration)) { 166 mIsRunning = false; 167 168 if (mListener != null) { 169 mListener.onAnimationEnd(); 170 } 171 } 172 } 173 174 if (mIsRunning) { 175 // If we're still running, post another delayed runnable 176 sHandler.postDelayed(mRunnable, HANDLER_DELAY); 177 } 178 } 179 180 private final Runnable mRunnable = new Runnable() { 181 public void run() { 182 update(); 183 } 184 }; 185} 186