blob: 8103f4734f1c1b0e16c0fe2820498115536634d1 [file] [log] [blame]
John Reck8d8af3c2014-07-01 15:23:45 -07001/*
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 android.view;
18
19import android.animation.ValueAnimator;
20
21import java.util.ArrayList;
22
23/**
24 * This class provides compatibility for things like start listeners &
25 * start delays for use by ViewPropertyAnimator and ObjectAnimator
26 * @hide
27 */
28public class RenderNodeAnimatorCompat extends RenderNodeAnimator {
29
30 private long mUnscaledStartDelay = 0;
31 private long mStartDelay = 0;
32 private long mStartTime;
33 private boolean mCanceled;
John Reckd3de42c2014-07-15 14:29:33 -070034 private boolean mStarted;
John Reck8d8af3c2014-07-01 15:23:45 -070035
36 public RenderNodeAnimatorCompat(int property, float finalValue) {
37 super(property, finalValue);
38 }
39
40 @Override
41 public void setStartDelay(long startDelay) {
42 mUnscaledStartDelay = startDelay;
43 mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay);
44 }
45
46 @Override
47 public long getStartDelay() {
48 return mUnscaledStartDelay;
49 }
50
51 @Override
52 public void start() {
John Reckd3de42c2014-07-15 14:29:33 -070053 mStarted = true;
John Reck8d8af3c2014-07-01 15:23:45 -070054 if (mStartDelay <= 0) {
55 doStart();
56 } else {
57 getHelper().addDelayedAnimation(this);
58 }
59 }
60
John Reckd3de42c2014-07-15 14:29:33 -070061 @Override
62 public boolean isStarted() {
63 return mStarted;
64 }
65
John Reck8d8af3c2014-07-01 15:23:45 -070066 private void doStart() {
67 if (!mCanceled) {
68 super.start();
69 }
70 }
71
72 @Override
73 public void cancel() {
74 mCanceled = true;
75 super.cancel();
76 }
77
78 /**
79 * @return true if the animator was started, false if still delayed
80 */
81 private boolean processDelayed(long frameTimeMs) {
82 if (mCanceled) return true;
83
84 if (mStartTime == 0) {
85 mStartTime = frameTimeMs;
86 } else if ((frameTimeMs - mStartTime) >= mStartDelay) {
87 doStart();
88 return true;
89 }
90 return false;
91 }
92
93 private static AnimationHelper getHelper() {
94 AnimationHelper helper = sAnimationHelper.get();
95 if (helper == null) {
96 helper = new AnimationHelper();
97 sAnimationHelper.set(helper);
98 }
99 return helper;
100 }
101
102 private static ThreadLocal<AnimationHelper> sAnimationHelper =
103 new ThreadLocal<AnimationHelper>();
104
105 private static class AnimationHelper implements Runnable {
106
107 private ArrayList<RenderNodeAnimatorCompat> mDelayedAnims = new ArrayList<RenderNodeAnimatorCompat>();
108 private final Choreographer mChoreographer;
109 private boolean mCallbackScheduled;
110
111 public AnimationHelper() {
112 mChoreographer = Choreographer.getInstance();
113 }
114
115 public void addDelayedAnimation(RenderNodeAnimatorCompat animator) {
116 mDelayedAnims.add(animator);
117 scheduleCallback();
118 }
119
120 private void scheduleCallback() {
121 if (!mCallbackScheduled) {
122 mCallbackScheduled = true;
123 mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null);
124 }
125 }
126
127 @Override
128 public void run() {
129 long frameTimeMs = mChoreographer.getFrameTime();
130 mCallbackScheduled = false;
131
132 int end = 0;
133 for (int i = 0; i < mDelayedAnims.size(); i++) {
134 RenderNodeAnimatorCompat animator = mDelayedAnims.get(i);
135 if (!animator.processDelayed(frameTimeMs)) {
136 if (end != i) {
137 mDelayedAnims.set(end, animator);
138 }
139 end++;
140 }
141 }
142 while (mDelayedAnims.size() > end) {
143 mDelayedAnims.remove(mDelayedAnims.size() - 1);
144 }
145
146 if (mDelayedAnims.size() > 0) {
147 scheduleCallback();
148 }
149 }
150 }
151}