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