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.support.annotation.NonNull; 20import android.view.animation.Interpolator; 21 22/** 23 * This class offers a very small subset of {@code ValueAnimator}'s API, but works pre-v11 too. 24 * <p> 25 * You shouldn't not instantiate this directly. Instead use {@code ViewUtils.createAnimator()}. 26 */ 27class ValueAnimatorCompat { 28 29 interface AnimatorUpdateListener { 30 /** 31 * <p>Notifies the occurrence of another frame of the animation.</p> 32 * 33 * @param animator The animation which was repeated. 34 */ 35 void onAnimationUpdate(ValueAnimatorCompat animator); 36 } 37 38 /** 39 * An animation listener receives notifications from an animation. 40 * Notifications indicate animation related events, such as the end or the 41 * repetition of the animation. 42 */ 43 interface AnimatorListener { 44 /** 45 * <p>Notifies the start of the animation.</p> 46 * 47 * @param animator The started animation. 48 */ 49 void onAnimationStart(ValueAnimatorCompat animator); 50 /** 51 * <p>Notifies the end of the animation. This callback is not invoked 52 * for animations with repeat count set to INFINITE.</p> 53 * 54 * @param animator The animation which reached its end. 55 */ 56 void onAnimationEnd(ValueAnimatorCompat animator); 57 /** 58 * <p>Notifies the cancellation of the animation. This callback is not invoked 59 * for animations with repeat count set to INFINITE.</p> 60 * 61 * @param animator The animation which was canceled. 62 */ 63 void onAnimationCancel(ValueAnimatorCompat animator); 64 } 65 66 static class AnimatorListenerAdapter implements AnimatorListener { 67 @Override 68 public void onAnimationStart(ValueAnimatorCompat animator) { 69 } 70 71 @Override 72 public void onAnimationEnd(ValueAnimatorCompat animator) { 73 } 74 75 @Override 76 public void onAnimationCancel(ValueAnimatorCompat animator) { 77 } 78 } 79 80 interface Creator { 81 @NonNull 82 ValueAnimatorCompat createAnimator(); 83 } 84 85 static abstract class Impl { 86 interface AnimatorUpdateListenerProxy { 87 void onAnimationUpdate(); 88 } 89 90 interface AnimatorListenerProxy { 91 void onAnimationStart(); 92 void onAnimationEnd(); 93 void onAnimationCancel(); 94 } 95 96 abstract void start(); 97 abstract boolean isRunning(); 98 abstract void setInterpolator(Interpolator interpolator); 99 abstract void addListener(AnimatorListenerProxy listener); 100 abstract void addUpdateListener(AnimatorUpdateListenerProxy updateListener); 101 abstract void setIntValues(int from, int to); 102 abstract int getAnimatedIntValue(); 103 abstract void setFloatValues(float from, float to); 104 abstract float getAnimatedFloatValue(); 105 abstract void setDuration(long duration); 106 abstract void cancel(); 107 abstract float getAnimatedFraction(); 108 abstract void end(); 109 abstract long getDuration(); 110 } 111 112 private final Impl mImpl; 113 114 ValueAnimatorCompat(Impl impl) { 115 mImpl = impl; 116 } 117 118 public void start() { 119 mImpl.start(); 120 } 121 122 public boolean isRunning() { 123 return mImpl.isRunning(); 124 } 125 126 public void setInterpolator(Interpolator interpolator) { 127 mImpl.setInterpolator(interpolator); 128 } 129 130 public void addUpdateListener(final AnimatorUpdateListener updateListener) { 131 if (updateListener != null) { 132 mImpl.addUpdateListener(new Impl.AnimatorUpdateListenerProxy() { 133 @Override 134 public void onAnimationUpdate() { 135 updateListener.onAnimationUpdate(ValueAnimatorCompat.this); 136 } 137 }); 138 } else { 139 mImpl.addUpdateListener(null); 140 } 141 } 142 143 public void addListener(final AnimatorListener listener) { 144 if (listener != null) { 145 mImpl.addListener(new Impl.AnimatorListenerProxy() { 146 @Override 147 public void onAnimationStart() { 148 listener.onAnimationStart(ValueAnimatorCompat.this); 149 } 150 151 @Override 152 public void onAnimationEnd() { 153 listener.onAnimationEnd(ValueAnimatorCompat.this); 154 } 155 156 @Override 157 public void onAnimationCancel() { 158 listener.onAnimationCancel(ValueAnimatorCompat.this); 159 } 160 }); 161 } else { 162 mImpl.addListener(null); 163 } 164 } 165 166 public void setIntValues(int from, int to) { 167 mImpl.setIntValues(from, to); 168 } 169 170 public int getAnimatedIntValue() { 171 return mImpl.getAnimatedIntValue(); 172 } 173 174 public void setFloatValues(float from, float to) { 175 mImpl.setFloatValues(from, to); 176 } 177 178 public float getAnimatedFloatValue() { 179 return mImpl.getAnimatedFloatValue(); 180 } 181 182 public void setDuration(long duration) { 183 mImpl.setDuration(duration); 184 } 185 186 public void cancel() { 187 mImpl.cancel(); 188 } 189 190 public float getAnimatedFraction() { 191 return mImpl.getAnimatedFraction(); 192 } 193 194 public void end() { 195 mImpl.end(); 196 } 197 198 public long getDuration() { 199 return mImpl.getDuration(); 200 } 201} 202