blob: 77a536a8ec49b60fb811911cd33a70f735a8cd05 [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
19import android.view.View;
20
21import java.util.ArrayList;
22
23/**
24 * Reveals a View with an animated clipping circle.
25 * The clipping is implemented efficiently by talking to a private reveal API on View.
26 * This hidden class currently only accessed by the {@link android.view.View}.
27 *
28 * @hide
29 */
30public class RevealAnimator extends ValueAnimator {
31 private final static String LOGTAG = "RevealAnimator";
32 private ValueAnimator.AnimatorListener mListener;
33 private ValueAnimator.AnimatorUpdateListener mUpdateListener;
34 private RevealCircle mReuseRevealCircle = new RevealCircle(0);
35 private RevealAnimator(final View clipView, final int x, final int y,
36 float startRadius, float endRadius, final boolean inverseClip) {
37
38 setObjectValues(new RevealCircle(startRadius), new RevealCircle(endRadius));
39 setEvaluator(new RevealCircleEvaluator(mReuseRevealCircle));
40
41 mUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
42 @Override
43 public void onAnimationUpdate(ValueAnimator animation) {
44 RevealCircle circle = (RevealCircle) animation.getAnimatedValue();
45 float radius = circle.getRadius();
46 clipView.setRevealClip(true, inverseClip, x, y, radius);
47 }
48 };
49 mListener = new AnimatorListenerAdapter() {
50 @Override
51 public void onAnimationCancel(Animator animation) {
52 clipView.setRevealClip(false, false, 0, 0, 0);
53 }
54
55 @Override
56 public void onAnimationEnd(Animator animation) {
57 clipView.setRevealClip(false, false, 0, 0, 0);
58 }
59 };
60 addUpdateListener(mUpdateListener);
61 addListener(mListener);
62 }
63
64 public static RevealAnimator ofRevealCircle(View clipView, int x, int y,
65 float startRadius, float endRadius, boolean inverseClip) {
66 RevealAnimator anim = new RevealAnimator(clipView, x, y,
67 startRadius, endRadius, inverseClip);
68 return anim;
69 }
70
71
72 /**
73 * {@inheritDoc}
74 */
75 @Override
76 public void removeAllUpdateListeners() {
77 super.removeAllUpdateListeners();
78 addUpdateListener(mUpdateListener);
79 }
80
81 /**
82 * {@inheritDoc}
83 */
84 @Override
85 public void removeAllListeners() {
86 super.removeAllListeners();
87 addListener(mListener);
88 }
89
90 /**
91 * {@inheritDoc}
92 */
93 @Override
94 public ArrayList<AnimatorListener> getListeners() {
95 ArrayList<AnimatorListener> allListeners =
96 (ArrayList<AnimatorListener>) super.getListeners().clone();
97 allListeners.remove(mListener);
98 return allListeners;
99 }
100
101 private class RevealCircle {
102 float mRadius;
103
104 public RevealCircle(float radius) {
105 mRadius = radius;
106 }
107
108 public void setRadius(float radius) {
109 mRadius = radius;
110 }
111
112 public float getRadius() {
113 return mRadius;
114 }
115 }
116
117 private class RevealCircleEvaluator implements TypeEvaluator<RevealCircle> {
118
119 private RevealCircle mRevealCircle;
120
121 public RevealCircleEvaluator() {
122 }
123
124 public RevealCircleEvaluator(RevealCircle reuseCircle) {
125 mRevealCircle = reuseCircle;
126 }
127
128 @Override
129 public RevealCircle evaluate(float fraction, RevealCircle startValue,
130 RevealCircle endValue) {
131 float currentRadius = startValue.mRadius
132 + ((endValue.mRadius - startValue.mRadius) * fraction);
133 if (mRevealCircle == null) {
134 return new RevealCircle(currentRadius);
135 } else {
136 mRevealCircle.setRadius(currentRadius);
137 return mRevealCircle;
138 }
139 }
140 }
141}