mTarget;
10 |
11 | public SupportAnimator(RevealAnimator target) {
12 | mTarget = new WeakReference<>(target);
13 | }
14 |
15 | /**
16 | * @return true if using native android animation framework, otherwise is
17 | * nineoldandroids
18 | */
19 | public abstract boolean isNativeAnimator();
20 |
21 | /**
22 | * @return depends from {@link android.os.Build.VERSION} if sdk version
23 | * {@link android.os.Build.VERSION_CODES#LOLLIPOP} and greater will return
24 | * {@link android.animation.Animator} otherwise {@link com.nineoldandroids.animation.Animator}
25 | */
26 | public abstract Object get();
27 |
28 | /**
29 | * Starts this animation. If the animation has a nonzero startDelay, the animation will start
30 | * running after that delay elapses. A non-delayed animation will have its initial
31 | * value(s) set immediately, followed by calls to
32 | * {@link android.animation.Animator.AnimatorListener#onAnimationStart(android.animation.Animator)}
33 | * for any listeners of this animator.
34 | *
35 | * The animation started by calling this method will be run on the thread that called
36 | * this method. This thread should have a Looper on it (a runtime exception will be thrown if
37 | * this is not the case). Also, if the animation will animate
38 | * properties of objects in the view hierarchy, then the calling thread should be the UI
39 | * thread for that view hierarchy.
40 | */
41 | public abstract void start();
42 |
43 | /**
44 | * Sets the duration of the animation.
45 | *
46 | * @param duration The length of the animation, in milliseconds.
47 | */
48 | public abstract void setDuration(int duration);
49 |
50 | /**
51 | * The time interpolator used in calculating the elapsed fraction of the
52 | * animation. The interpolator determines whether the animation runs with
53 | * linear or non-linear motion, such as acceleration and deceleration. The
54 | * default value is {@link android.view.animation.AccelerateDecelerateInterpolator}.
55 | *
56 | * @param value the interpolator to be used by this animation
57 | */
58 | public abstract void setInterpolator(Interpolator value);
59 |
60 |
61 | /**
62 | * Adds a listener to the set of listeners that are sent events through the life of an
63 | * animation, such as start, repeat, and end.
64 | *
65 | * @param listener the listener to be added to the current set of listeners for this animation.
66 | */
67 | public abstract void addListener(AnimatorListener listener);
68 |
69 |
70 | /**
71 | * Returns whether this Animator is currently running (having been started and gone past any
72 | * initial startDelay period and not yet ended).
73 | *
74 | * @return Whether the Animator is running.
75 | */
76 | public abstract boolean isRunning();
77 |
78 |
79 | /**
80 | * Cancels the animation. Unlike {@link #end()}, cancel()
causes the animation to
81 | * stop in its tracks, sending an
82 | * {@link AnimatorListener#onAnimationCancel()} to
83 | * its listeners, followed by an
84 | * {@link AnimatorListener#onAnimationEnd()} message.
85 | *
86 | * This method must be called on the thread that is running the animation.
87 | */
88 | public abstract void cancel();
89 |
90 | /**
91 | * Ends the animation. This causes the animation to assign the end value of the property being
92 | * animated, then calling the
93 | * {@link AnimatorListener#onAnimationEnd()} method on
94 | * its listeners.
95 | *
96 | * This method must be called on the thread that is running the animation.
97 | */
98 | public void end() {
99 | }
100 |
101 | /**
102 | * This method tells the object to use appropriate information to extract
103 | * starting values for the animation. For example, a AnimatorSet object will pass
104 | * this call to its child objects to tell them to set up the values. A
105 | * ObjectAnimator object will use the information it has about its target object
106 | * and PropertyValuesHolder objects to get the start values for its properties.
107 | * A ValueAnimator object will ignore the request since it does not have enough
108 | * information (such as a target object) to gather these values.
109 | */
110 | public void setupStartValues() {
111 | }
112 |
113 | /**
114 | * This method tells the object to use appropriate information to extract
115 | * ending values for the animation. For example, a AnimatorSet object will pass
116 | * this call to its child objects to tell them to set up the values. A
117 | * ObjectAnimator object will use the information it has about its target object
118 | * and PropertyValuesHolder objects to get the start values for its properties.
119 | * A ValueAnimator object will ignore the request since it does not have enough
120 | * information (such as a target object) to gather these values.
121 | */
122 | public void setupEndValues() {
123 | }
124 |
125 | /**
126 | * Experimental feature
127 | */
128 | public SupportAnimator reverse() {
129 | if (isRunning()) {
130 | return null;
131 | }
132 |
133 | RevealAnimator target = mTarget.get();
134 | if (target != null) {
135 | return target.startReverseAnimation();
136 | }
137 |
138 | return null;
139 | }
140 |
141 | /**
142 | * An animation listener receives notifications from an animation.
143 | * Notifications indicate animation related events, such as the end or the
144 | * repetition of the animation.
145 | */
146 | public interface AnimatorListener {
147 | /**
148 | * Notifies the start of the animation.
149 | */
150 | void onAnimationStart();
151 |
152 | /**
153 | * Notifies the end of the animation. This callback is not invoked
154 | * for animations with repeat count set to INFINITE.
155 | */
156 | void onAnimationEnd();
157 |
158 | /**
159 | * Notifies the cancellation of the animation. This callback is not invoked
160 | * for animations with repeat count set to INFINITE.
161 | */
162 | void onAnimationCancel();
163 |
164 | /**
165 | * Notifies the repetition of the animation.
166 | */
167 | void onAnimationRepeat();
168 | }
169 |
170 | /**
171 | * Provides default implementation for AnimatorListener.
172 | */
173 | public static abstract class SimpleAnimatorListener implements AnimatorListener {
174 |
175 | @Override
176 | public void onAnimationStart() {
177 |
178 | }
179 |
180 | @Override
181 | public void onAnimationEnd() {
182 |
183 | }
184 |
185 | @Override
186 | public void onAnimationCancel() {
187 |
188 | }
189 |
190 | @Override
191 | public void onAnimationRepeat() {
192 |
193 | }
194 | }
195 |
196 | }
197 |
--------------------------------------------------------------------------------
/fab-transformation/src/main/java/io/codetail/animation/SupportAnimatorLollipop.java:
--------------------------------------------------------------------------------
1 | package io.codetail.animation;
2 |
3 | import android.animation.Animator;
4 | import android.annotation.TargetApi;
5 | import android.os.Build;
6 | import android.view.animation.Interpolator;
7 |
8 | import java.lang.ref.WeakReference;
9 |
10 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
11 | final class SupportAnimatorLollipop extends SupportAnimator {
12 |
13 | WeakReference mAnimator;
14 |
15 | SupportAnimatorLollipop(Animator animator, RevealAnimator target) {
16 | super(target);
17 | mAnimator = new WeakReference<>(animator);
18 | }
19 |
20 | @Override
21 | public boolean isNativeAnimator() {
22 | return true;
23 | }
24 |
25 | @Override
26 | public Object get() {
27 | return mAnimator.get();
28 | }
29 |
30 |
31 | @Override
32 | public void start() {
33 | Animator a = mAnimator.get();
34 | if (a != null) {
35 | a.start();
36 | }
37 | }
38 |
39 | @Override
40 | public void setDuration(int duration) {
41 | Animator a = mAnimator.get();
42 | if (a != null) {
43 | a.setDuration(duration);
44 | }
45 | }
46 |
47 | @Override
48 | public void setInterpolator(Interpolator value) {
49 | Animator a = mAnimator.get();
50 | if (a != null) {
51 | a.setInterpolator(value);
52 | }
53 | }
54 |
55 | @Override
56 | public void addListener(final AnimatorListener listener) {
57 | Animator a = mAnimator.get();
58 | if (a == null) {
59 | return;
60 | }
61 |
62 | if (listener == null) {
63 | a.addListener(null);
64 | return;
65 | }
66 |
67 | a.addListener(new Animator.AnimatorListener() {
68 | @Override
69 | public void onAnimationStart(Animator animation) {
70 | listener.onAnimationStart();
71 | }
72 |
73 | @Override
74 | public void onAnimationEnd(Animator animation) {
75 | listener.onAnimationEnd();
76 | }
77 |
78 | @Override
79 | public void onAnimationCancel(Animator animation) {
80 | listener.onAnimationCancel();
81 | }
82 |
83 | @Override
84 | public void onAnimationRepeat(Animator animation) {
85 | listener.onAnimationRepeat();
86 | }
87 | });
88 | }
89 |
90 | @Override
91 | public boolean isRunning() {
92 | Animator a = mAnimator.get();
93 | return a != null && a.isRunning();
94 | }
95 |
96 | @Override
97 | public void cancel() {
98 | Animator a = mAnimator.get();
99 | if (a != null) {
100 | a.cancel();
101 | }
102 | }
103 |
104 | @Override
105 | public void end() {
106 | Animator a = mAnimator.get();
107 | if (a != null) {
108 | a.end();
109 | }
110 | }
111 |
112 | @Override
113 | public void setupStartValues() {
114 | Animator a = mAnimator.get();
115 | if (a != null) {
116 | a.setupStartValues();
117 | }
118 | }
119 |
120 | @Override
121 | public void setupEndValues() {
122 | Animator a = mAnimator.get();
123 | if (a != null) {
124 | a.setupEndValues();
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/fab-transformation/src/main/java/io/codetail/animation/SupportAnimatorPreL.java:
--------------------------------------------------------------------------------
1 | package io.codetail.animation;
2 |
3 | import android.view.animation.Interpolator;
4 |
5 | import com.nineoldandroids.animation.Animator;
6 |
7 | import java.lang.ref.WeakReference;
8 |
9 | final class SupportAnimatorPreL extends SupportAnimator {
10 |
11 | WeakReference mAnimator;
12 |
13 | SupportAnimatorPreL(Animator animator, RevealAnimator target) {
14 | super(target);
15 | mAnimator = new WeakReference<>(animator);
16 | }
17 |
18 | @Override
19 | public boolean isNativeAnimator() {
20 | return false;
21 | }
22 |
23 | @Override
24 | public Object get() {
25 | return mAnimator.get();
26 | }
27 |
28 | @Override
29 | public void start() {
30 | Animator a = mAnimator.get();
31 | if (a != null) {
32 | a.start();
33 | }
34 | }
35 |
36 | @Override
37 | public void setDuration(int duration) {
38 | Animator a = mAnimator.get();
39 | if (a != null) {
40 | a.setDuration(duration);
41 | }
42 | }
43 |
44 | @Override
45 | public void setInterpolator(Interpolator value) {
46 | Animator a = mAnimator.get();
47 | if (a != null) {
48 | a.setInterpolator(value);
49 | }
50 | }
51 |
52 | @Override
53 | public void addListener(final AnimatorListener listener) {
54 | Animator a = mAnimator.get();
55 | if (a == null) {
56 | return;
57 | }
58 |
59 | if (listener == null) {
60 | a.addListener(null);
61 | return;
62 | }
63 |
64 | a.addListener(new Animator.AnimatorListener() {
65 | @Override
66 | public void onAnimationStart(Animator animation) {
67 | listener.onAnimationStart();
68 | }
69 |
70 | @Override
71 | public void onAnimationEnd(Animator animation) {
72 | listener.onAnimationEnd();
73 | }
74 |
75 | @Override
76 | public void onAnimationCancel(Animator animation) {
77 | listener.onAnimationCancel();
78 | }
79 |
80 | @Override
81 | public void onAnimationRepeat(Animator animation) {
82 | listener.onAnimationRepeat();
83 | }
84 | });
85 | }
86 |
87 | @Override
88 | public boolean isRunning() {
89 | Animator a = mAnimator.get();
90 | return a != null && a.isRunning();
91 | }
92 |
93 | @Override
94 | public void cancel() {
95 | Animator a = mAnimator.get();
96 | if (a != null) {
97 | a.cancel();
98 | }
99 | }
100 |
101 | @Override
102 | public void end() {
103 | Animator a = mAnimator.get();
104 | if (a != null) {
105 | a.end();
106 | }
107 | }
108 |
109 | @Override
110 | public void setupStartValues() {
111 | Animator a = mAnimator.get();
112 | if (a != null) {
113 | a.setupStartValues();
114 | }
115 | }
116 |
117 | @Override
118 | public void setupEndValues() {
119 | Animator a = mAnimator.get();
120 | if (a != null) {
121 | a.setupEndValues();
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/fab-transformation/src/main/java/io/codetail/animation/ViewAnimationUtils.java:
--------------------------------------------------------------------------------
1 | package io.codetail.animation;
2 |
3 | import android.annotation.TargetApi;
4 | import android.os.Build;
5 | import android.view.View;
6 | import android.view.animation.AccelerateDecelerateInterpolator;
7 |
8 | import com.nineoldandroids.animation.Animator;
9 | import com.nineoldandroids.animation.ObjectAnimator;
10 | import com.nineoldandroids.view.ViewHelper;
11 | import com.nineoldandroids.view.ViewPropertyAnimator;
12 |
13 | import java.lang.ref.WeakReference;
14 |
15 | import io.codetail.animation.RevealAnimator.RevealInfo;
16 |
17 | import static android.os.Build.VERSION.SDK_INT;
18 | import static android.os.Build.VERSION_CODES.LOLLIPOP;
19 | import static io.codetail.animation.RevealAnimator.CLIP_RADIUS;
20 |
21 | public class ViewAnimationUtils {
22 |
23 | public static final int SCALE_UP_DURATION = 500;
24 | private final static boolean LOLLIPOP_PLUS = SDK_INT >= LOLLIPOP;
25 |
26 | /**
27 | * Returns an Animator which can animate a clipping circle.
28 | *
29 | * Any shadow cast by the View will respect the circular clip from this animator.
30 | *
31 | * Only a single non-rectangular clip can be applied on a View at any time.
32 | * Views clipped by a circular reveal animation take priority over
33 | * {@link View#setClipToOutline(boolean) View Outline clipping}.
34 | *
35 | * Note that the animation returned here is a one-shot animation. It cannot
36 | * be re-used, and once started it cannot be paused or resumed.
37 | *
38 | * @param view The View will be clipped to the animating circle.
39 | * @param centerX The x coordinate of the center of the animating circle.
40 | * @param centerY The y coordinate of the center of the animating circle.
41 | * @param startRadius The starting radius of the animating circle.
42 | * @param endRadius The ending radius of the animating circle.
43 | */
44 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
45 | public static SupportAnimator createCircularReveal(View view,
46 | int centerX, int centerY,
47 | float startRadius, float endRadius) {
48 |
49 | if (!(view.getParent() instanceof RevealAnimator)) {
50 | throw new IllegalArgumentException("View must be inside RevealFrameLayout or RevealLinearLayout.");
51 | }
52 |
53 | RevealAnimator revealLayout = (RevealAnimator) view.getParent();
54 | revealLayout.attachRevealInfo(new RevealInfo(centerX, centerY, startRadius, endRadius,
55 | new WeakReference<>(view)));
56 |
57 | if (LOLLIPOP_PLUS) {
58 | return new SupportAnimatorLollipop(android.view.ViewAnimationUtils
59 | .createCircularReveal(view, centerX, centerY, startRadius, endRadius), revealLayout);
60 | }
61 |
62 | ObjectAnimator reveal = ObjectAnimator.ofFloat(revealLayout, CLIP_RADIUS,
63 | startRadius, endRadius);
64 | reveal.addListener(getRevealFinishListener(revealLayout));
65 |
66 | return new SupportAnimatorPreL(reveal, revealLayout);
67 | }
68 |
69 | private static Animator.AnimatorListener getRevealFinishListener(RevealAnimator target) {
70 | if (SDK_INT >= 18) {
71 | return new RevealAnimator.RevealFinishedJellyBeanMr2(target);
72 | } else if (SDK_INT >= 14) {
73 | return new RevealAnimator.RevealFinishedIceCreamSandwich(target);
74 | } else {
75 | return new RevealAnimator.RevealFinishedGingerbread(target);
76 | }
77 | }
78 |
79 | /**
80 | * Lifting view
81 | *
82 | * @param view The animation target
83 | * @param baseRotation initial Rotation X in 3D space
84 | * @param fromY initial Y position of view
85 | * @param duration aniamtion duration
86 | * @param startDelay start delay before animation begin
87 | */
88 | @Deprecated
89 | public static void liftingFromBottom(View view, float baseRotation, float fromY, int duration, int startDelay) {
90 | ViewHelper.setRotationX(view, baseRotation);
91 | ViewHelper.setTranslationY(view, fromY);
92 |
93 | ViewPropertyAnimator
94 | .animate(view)
95 | .setInterpolator(new AccelerateDecelerateInterpolator())
96 | .setDuration(duration)
97 | .setStartDelay(startDelay)
98 | .rotationX(0)
99 | .translationY(0)
100 | .start();
101 |
102 | }
103 |
104 | /**
105 | * Lifting view
106 | *
107 | * @param view The animation target
108 | * @param baseRotation initial Rotation X in 3D space
109 | * @param duration aniamtion duration
110 | * @param startDelay start delay before animation begin
111 | */
112 | @Deprecated
113 | public static void liftingFromBottom(View view, float baseRotation, int duration, int startDelay) {
114 | ViewHelper.setRotationX(view, baseRotation);
115 | ViewHelper.setTranslationY(view, view.getHeight() / 3);
116 |
117 | ViewPropertyAnimator
118 | .animate(view)
119 | .setInterpolator(new AccelerateDecelerateInterpolator())
120 | .setDuration(duration)
121 | .setStartDelay(startDelay)
122 | .rotationX(0)
123 | .translationY(0)
124 | .start();
125 |
126 | }
127 |
128 | /**
129 | * Lifting view
130 | *
131 | * @param view The animation target
132 | * @param baseRotation initial Rotation X in 3D space
133 | * @param duration aniamtion duration
134 | */
135 | @Deprecated
136 | public static void liftingFromBottom(View view, float baseRotation, int duration) {
137 | ViewHelper.setRotationX(view, baseRotation);
138 | ViewHelper.setTranslationY(view, view.getHeight() / 3);
139 |
140 | ViewPropertyAnimator
141 | .animate(view)
142 | .setInterpolator(new AccelerateDecelerateInterpolator())
143 | .setDuration(duration)
144 | .rotationX(0)
145 | .translationY(0)
146 | .start();
147 |
148 | }
149 |
150 | static class SimpleAnimationListener implements Animator.AnimatorListener {
151 |
152 | @Override
153 | public void onAnimationStart(Animator animation) {
154 |
155 | }
156 |
157 | @Override
158 | public void onAnimationEnd(Animator animation) {
159 |
160 | }
161 |
162 | @Override
163 | public void onAnimationCancel(Animator animation) {
164 |
165 | }
166 |
167 | @Override
168 | public void onAnimationRepeat(Animator animation) {
169 |
170 | }
171 | }
172 |
173 | }
174 |
--------------------------------------------------------------------------------
/fab-transformation/src/main/java/io/codetail/widget/RevealFrameLayout.java:
--------------------------------------------------------------------------------
1 | package io.codetail.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Path;
6 | import android.graphics.Rect;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.widget.FrameLayout;
10 |
11 | import io.codetail.animation.RevealAnimator;
12 | import io.codetail.animation.SupportAnimator;
13 | import io.codetail.animation.ViewAnimationUtils;
14 |
15 | public class RevealFrameLayout extends FrameLayout implements RevealAnimator {
16 |
17 | private final Rect mTargetBounds = new Rect();
18 | private Path mRevealPath;
19 | private RevealInfo mRevealInfo;
20 | private boolean mRunning;
21 | private float mRadius;
22 |
23 | public RevealFrameLayout(Context context) {
24 | this(context, null);
25 | }
26 |
27 | public RevealFrameLayout(Context context, AttributeSet attrs) {
28 | this(context, attrs, 0);
29 | }
30 |
31 | public RevealFrameLayout(Context context, AttributeSet attrs, int defStyle) {
32 | super(context, attrs, defStyle);
33 | mRevealPath = new Path();
34 | }
35 |
36 | @Override
37 | public void onRevealAnimationStart() {
38 | mRunning = true;
39 | }
40 |
41 | @Override
42 | public void onRevealAnimationEnd() {
43 | mRunning = false;
44 | invalidate(mTargetBounds);
45 | }
46 |
47 | @Override
48 | public void onRevealAnimationCancel() {
49 | onRevealAnimationEnd();
50 | }
51 |
52 | /**
53 | * Circle radius size
54 | *
55 | * @hide
56 | */
57 | @Override
58 | public float getRevealRadius() {
59 | return mRadius;
60 | }
61 |
62 | /**
63 | * Circle radius size
64 | *
65 | * @hide
66 | */
67 | @Override
68 | public void setRevealRadius(float radius) {
69 | mRadius = radius;
70 | invalidate(mTargetBounds);
71 | }
72 |
73 | /**
74 | * @hide
75 | */
76 | @Override
77 | public void attachRevealInfo(RevealInfo info) {
78 | info.getTarget().getHitRect(mTargetBounds);
79 | mRevealInfo = info;
80 | }
81 |
82 | /**
83 | * @hide
84 | */
85 | @Override
86 | public SupportAnimator startReverseAnimation() {
87 | if (mRevealInfo != null && mRevealInfo.hasTarget() && !mRunning) {
88 | return ViewAnimationUtils.createCircularReveal(mRevealInfo.getTarget(),
89 | mRevealInfo.centerX, mRevealInfo.centerY,
90 | mRevealInfo.endRadius, mRevealInfo.startRadius);
91 | }
92 | return null;
93 | }
94 |
95 | @Override
96 | protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
97 | if (mRunning && child == mRevealInfo.getTarget()) {
98 | final int state = canvas.save();
99 |
100 | mRevealPath.reset();
101 | mRevealPath.addCircle(mRevealInfo.centerX, mRevealInfo.centerY, mRadius, Path.Direction.CW);
102 |
103 | canvas.clipPath(mRevealPath);
104 |
105 | boolean isInvalided = super.drawChild(canvas, child, drawingTime);
106 |
107 | canvas.restoreToCount(state);
108 |
109 | return isInvalided;
110 | }
111 |
112 | return super.drawChild(canvas, child, drawingTime);
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/fab-transformation/src/main/java/io/codetail/widget/RevealLinearLayout.java:
--------------------------------------------------------------------------------
1 | package io.codetail.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Path;
6 | import android.graphics.Rect;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.widget.LinearLayout;
10 |
11 | import io.codetail.animation.RevealAnimator;
12 | import io.codetail.animation.SupportAnimator;
13 | import io.codetail.animation.ViewAnimationUtils;
14 |
15 | public class RevealLinearLayout extends LinearLayout implements RevealAnimator {
16 |
17 | private final Rect mTargetBounds = new Rect();
18 | private Path mRevealPath;
19 | private RevealInfo mRevealInfo;
20 | private boolean mRunning;
21 | private float mRadius;
22 |
23 | public RevealLinearLayout(Context context) {
24 | this(context, null);
25 | }
26 |
27 | public RevealLinearLayout(Context context, AttributeSet attrs) {
28 | this(context, attrs, 0);
29 | }
30 |
31 | public RevealLinearLayout(Context context, AttributeSet attrs, int defStyle) {
32 | super(context, attrs);
33 | mRevealPath = new Path();
34 | }
35 |
36 | @Override
37 | public void onRevealAnimationStart() {
38 | mRunning = true;
39 | }
40 |
41 | @Override
42 | public void onRevealAnimationEnd() {
43 | mRunning = false;
44 | invalidate(mTargetBounds);
45 | }
46 |
47 | @Override
48 | public void onRevealAnimationCancel() {
49 | onRevealAnimationEnd();
50 | }
51 |
52 | /**
53 | * Circle radius size
54 | *
55 | * @hide
56 | */
57 | @Override
58 | public float getRevealRadius() {
59 | return mRadius;
60 | }
61 |
62 | /**
63 | * Circle radius size
64 | *
65 | * @hide
66 | */
67 | @Override
68 | public void setRevealRadius(float radius) {
69 | mRadius = radius;
70 | invalidate(mTargetBounds);
71 | }
72 |
73 | /**
74 | * @hide
75 | */
76 | @Override
77 | public void attachRevealInfo(RevealInfo info) {
78 | info.getTarget().getHitRect(mTargetBounds);
79 | mRevealInfo = info;
80 | }
81 |
82 | /**
83 | * @hide
84 | */
85 | @Override
86 | public SupportAnimator startReverseAnimation() {
87 | if (mRevealInfo != null && mRevealInfo.hasTarget() && !mRunning) {
88 | return ViewAnimationUtils.createCircularReveal(mRevealInfo.getTarget(),
89 | mRevealInfo.centerX, mRevealInfo.centerY,
90 | mRevealInfo.endRadius, mRevealInfo.startRadius);
91 | }
92 | return null;
93 | }
94 |
95 | @Override
96 | protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
97 | if (mRunning && child == mRevealInfo.getTarget()) {
98 | final int state = canvas.save();
99 |
100 | mRevealPath.reset();
101 | mRevealPath.addCircle(mRevealInfo.centerX, mRevealInfo.centerY, mRadius, Path.Direction.CW);
102 |
103 | canvas.clipPath(mRevealPath);
104 |
105 | boolean isInvalided = super.drawChild(canvas, child, drawingTime);
106 |
107 | canvas.restoreToCount(state);
108 |
109 | return isInvalided;
110 | }
111 |
112 | return super.drawChild(canvas, child, drawingTime);
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | VERSION_NAME=1.0.0
2 | VERSION_CODE=4
3 | GROUP=com.konifar
4 | ARTIFACT_ID=fab-transformation
5 |
6 | COMPILE_SDK_VERSION=22
7 | BUILD_TOOLS_VERSION=22.0.1
8 | TARGET_SDK_VERSION=22
9 | RENDERSCRIPT_TARGET_API=22
10 | MIN_SDK_VERSION=9
11 |
12 | POM_DESCRIPTION=Support Floating Action Button transformation for Android
13 | POM_URL=https://github.com/konifar/fab-transformation
14 | POM_SCM_URL=git@github.com:konifar/fab-transformation.git
15 | POM_SCM_CONNECTION=git@github.com:konifar/fab-transformation.git
16 | POM_SCM_DEV_CONNECTION=scm:git@github.com:konifar/fab-transformation.git
17 | POM_LICENCE_NAME=The MIT License
18 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
19 | POM_LICENCE_DIST=repo
20 | POM_DEVELOPER_ID=konifar
21 | POM_DEVELOPER_NAME=konifar
22 | POM_DEVELOPER_EMAIL=yahpeycoy0403@gmail.com
23 | POM_DEVELOPER_URL=konifar.com
24 | ISSUE_URL=https://github.com/konifar/fab-transformation/issues
25 |
26 | SUPPORT_PACKAGE_VERSION=22.2.1
27 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/konifar/fab-transformation/fd176bfff9c5ad4fc6bad28ffec77cbdaf4089d5/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Nov 29 21:12:05 CST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':fab-transformation', ':example'
2 |
--------------------------------------------------------------------------------