blob: e363a773e56db3254a36771c68c470d255079771 [file] [log] [blame]
ztenghui4dc16b32014-03-25 09:58:34 -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.animation;
18
John Reckd3de42c2014-07-15 14:29:33 -070019import android.view.RenderNodeAnimator;
ztenghui4dc16b32014-03-25 09:58:34 -070020import android.view.View;
21
ztenghui4dc16b32014-03-25 09:58:34 -070022/**
23 * Reveals a View with an animated clipping circle.
24 * The clipping is implemented efficiently by talking to a private reveal API on View.
25 * This hidden class currently only accessed by the {@link android.view.View}.
26 *
27 * @hide
28 */
29public class RevealAnimator extends ValueAnimator {
ztenghui4dc16b32014-03-25 09:58:34 -070030
John Reckd3de42c2014-07-15 14:29:33 -070031 private View mClipView;
32 private int mX, mY;
John Reckd3de42c2014-07-15 14:29:33 -070033 private float mStartRadius, mEndRadius;
34 private float mDelta;
35 private boolean mMayRunAsync;
ztenghui4dc16b32014-03-25 09:58:34 -070036
John Reckd3de42c2014-07-15 14:29:33 -070037 // If this is null, we are running on the UI thread driven by the base
38 // ValueAnimator class. If this is not null, forward requests on to this
39 // Animator instead.
40 private RenderNodeAnimator mRtAnimator;
ztenghui4dc16b32014-03-25 09:58:34 -070041
John Reckd3de42c2014-07-15 14:29:33 -070042 public RevealAnimator(View clipView, int x, int y,
Chris Craikaf4d04c2014-07-29 12:50:14 -070043 float startRadius, float endRadius) {
John Reckd3de42c2014-07-15 14:29:33 -070044 mClipView = clipView;
45 mStartRadius = startRadius;
46 mEndRadius = endRadius;
47 mDelta = endRadius - startRadius;
48 mX = x;
49 mY = y;
John Reckd3de42c2014-07-15 14:29:33 -070050 super.setValues(PropertyValuesHolder.ofFloat("radius", startRadius, endRadius));
ztenghui4dc16b32014-03-25 09:58:34 -070051 }
52
John Reckd3de42c2014-07-15 14:29:33 -070053 @Override
54 void animateValue(float fraction) {
55 super.animateValue(fraction);
56 fraction = getAnimatedFraction();
57 float radius = mStartRadius + (mDelta * fraction);
Chris Craikaf4d04c2014-07-29 12:50:14 -070058 mClipView.setRevealClip(true, mX, mY, radius);
John Reckd3de42c2014-07-15 14:29:33 -070059 }
60
61 @Override
62 protected void endAnimation(AnimationHandler handler) {
Chris Craikaf4d04c2014-07-29 12:50:14 -070063 mClipView.setRevealClip(false, 0, 0, 0);
John Reckd3de42c2014-07-15 14:29:33 -070064 super.endAnimation(handler);
65 }
66
67 @Override
68 public void setAllowRunningAsynchronously(boolean mayRunAsync) {
69 mMayRunAsync = mayRunAsync;
70 }
71
72 private boolean canRunAsync() {
73 if (!mMayRunAsync) {
74 return false;
75 }
76 if (mUpdateListeners != null && mUpdateListeners.size() > 0) {
77 return false;
78 }
79 // TODO: Have RNA support this
80 if (getRepeatCount() != 0) {
81 return false;
82 }
83 return true;
84 }
85
86 @Override
87 public void start() {
88 if (mRtAnimator != null) {
89 mRtAnimator.end();
90 mRtAnimator = null;
91 }
92 if (canRunAsync()) {
Chris Craikaf4d04c2014-07-29 12:50:14 -070093 mRtAnimator = new RenderNodeAnimator(mX, mY, mStartRadius, mEndRadius);
John Reckd3de42c2014-07-15 14:29:33 -070094 mRtAnimator.setDuration(getDuration());
95 mRtAnimator.setInterpolator(getInterpolator());
96 mRtAnimator.setTarget(mClipView);
97 // TODO: Listeners
98 mRtAnimator.start();
99 } else {
100 super.start();
101 }
102 }
103
104 @Override
105 public void cancel() {
106 if (mRtAnimator != null) {
107 mRtAnimator.cancel();
108 } else {
109 super.cancel();
110 }
111 }
112
113 @Override
114 public void end() {
115 if (mRtAnimator != null) {
116 mRtAnimator.end();
117 } else {
118 super.end();
119 }
120 }
121
122 @Override
123 public void resume() {
124 if (mRtAnimator != null) {
125 // TODO: Support? Reject?
126 } else {
127 super.resume();
128 }
129 }
130
131 @Override
132 public void pause() {
133 if (mRtAnimator != null) {
134 // TODO: see resume()
135 } else {
136 super.pause();
137 }
138 }
139
140 @Override
141 public boolean isRunning() {
142 if (mRtAnimator != null) {
143 return mRtAnimator.isRunning();
144 } else {
145 return super.isRunning();
146 }
147 }
148
149 @Override
150 public boolean isStarted() {
151 if (mRtAnimator != null) {
152 return mRtAnimator.isStarted();
153 } else {
154 return super.isStarted();
155 }
156 }
157
158 @Override
159 public void reverse() {
160 if (mRtAnimator != null) {
161 // TODO support
162 } else {
163 super.reverse();
164 }
165 }
166
167 @Override
John Reckc01bd112014-07-18 16:22:09 -0700168 public RevealAnimator clone() {
John Reckd3de42c2014-07-15 14:29:33 -0700169 RevealAnimator anim = (RevealAnimator) super.clone();
170 anim.mRtAnimator = null;
ztenghui4dc16b32014-03-25 09:58:34 -0700171 return anim;
172 }
ztenghui4dc16b32014-03-25 09:58:34 -0700173}