1/*
2 * Copyright (C) 2014 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 androidx.appcompat.view;
18
19import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20
21import android.view.View;
22import android.view.animation.Interpolator;
23
24import androidx.annotation.RestrictTo;
25import androidx.core.view.ViewPropertyAnimatorCompat;
26import androidx.core.view.ViewPropertyAnimatorListener;
27import androidx.core.view.ViewPropertyAnimatorListenerAdapter;
28
29import java.util.ArrayList;
30
31/**
32 * A very naive implementation of a set of
33 * {@link androidx.core.view.ViewPropertyAnimatorCompat}.
34 *
35 * @hide
36 */
37@RestrictTo(LIBRARY_GROUP)
38public class ViewPropertyAnimatorCompatSet {
39
40    final ArrayList<ViewPropertyAnimatorCompat> mAnimators;
41
42    private long mDuration = -1;
43    private Interpolator mInterpolator;
44    ViewPropertyAnimatorListener mListener;
45
46    private boolean mIsStarted;
47
48    public ViewPropertyAnimatorCompatSet() {
49        mAnimators = new ArrayList<ViewPropertyAnimatorCompat>();
50    }
51
52    public ViewPropertyAnimatorCompatSet play(ViewPropertyAnimatorCompat animator) {
53        if (!mIsStarted) {
54            mAnimators.add(animator);
55        }
56        return this;
57    }
58
59    public ViewPropertyAnimatorCompatSet playSequentially(ViewPropertyAnimatorCompat anim1,
60            ViewPropertyAnimatorCompat anim2) {
61        mAnimators.add(anim1);
62        anim2.setStartDelay(anim1.getDuration());
63        mAnimators.add(anim2);
64        return this;
65    }
66
67    public void start() {
68        if (mIsStarted) return;
69        for (ViewPropertyAnimatorCompat animator : mAnimators) {
70            if (mDuration >= 0) {
71                animator.setDuration(mDuration);
72            }
73            if (mInterpolator != null) {
74                animator.setInterpolator(mInterpolator);
75            }
76            if (mListener != null) {
77                animator.setListener(mProxyListener);
78            }
79            animator.start();
80        }
81
82        mIsStarted = true;
83    }
84
85    void onAnimationsEnded() {
86        mIsStarted = false;
87    }
88
89    public void cancel() {
90        if (!mIsStarted) {
91            return;
92        }
93        for (ViewPropertyAnimatorCompat animator : mAnimators) {
94            animator.cancel();
95        }
96        mIsStarted = false;
97    }
98
99    public ViewPropertyAnimatorCompatSet setDuration(long duration) {
100        if (!mIsStarted) {
101            mDuration = duration;
102        }
103        return this;
104    }
105
106    public ViewPropertyAnimatorCompatSet setInterpolator(Interpolator interpolator) {
107        if (!mIsStarted) {
108            mInterpolator = interpolator;
109        }
110        return this;
111    }
112
113    public ViewPropertyAnimatorCompatSet setListener(ViewPropertyAnimatorListener listener) {
114        if (!mIsStarted) {
115            mListener = listener;
116        }
117        return this;
118    }
119
120    private final ViewPropertyAnimatorListenerAdapter mProxyListener
121            = new ViewPropertyAnimatorListenerAdapter() {
122        private boolean mProxyStarted = false;
123        private int mProxyEndCount = 0;
124
125        @Override
126        public void onAnimationStart(View view) {
127            if (mProxyStarted) {
128                return;
129            }
130            mProxyStarted = true;
131            if (mListener != null) {
132                mListener.onAnimationStart(null);
133            }
134        }
135
136        void onEnd() {
137            mProxyEndCount = 0;
138            mProxyStarted = false;
139            onAnimationsEnded();
140        }
141
142        @Override
143        public void onAnimationEnd(View view) {
144            if (++mProxyEndCount == mAnimators.size()) {
145                if (mListener != null) {
146                    mListener.onAnimationEnd(null);
147                }
148                onEnd();
149            }
150        }
151    };
152}
153