From 19ebd4c28f0061496f5bbc097b621e31d4fa6a29 Mon Sep 17 00:00:00 2001 From: seven332 Date: Sun, 27 Mar 2016 18:13:35 +0800 Subject: [PATCH] Use my own reveal stuff --- .../ui/scene/GalleryCommentsScene.java | 22 +-- .../main/java/com/hippo/reveal/Reveal.java | 24 +++ .../com/hippo/reveal/RevealLinearLayout.java | 87 ++++++++ .../com/hippo/reveal/ViewAnimationUtils.java | 107 ++++++++++ .../io/codetail/animation/RevealAnimator.java | 147 -------------- .../codetail/animation/SupportAnimator.java | 186 ------------------ .../animation/SupportAnimatorImpl.java | 154 --------------- .../animation/ViewAnimationUtils.java | 157 --------------- .../codetail/widget/RevealLinearLayout.java | 115 ----------- .../res/layout/scene_gallery_comments.xml | 4 +- 10 files changed, 229 insertions(+), 774 deletions(-) create mode 100644 app/src/main/java/com/hippo/reveal/Reveal.java create mode 100644 app/src/main/java/com/hippo/reveal/RevealLinearLayout.java create mode 100644 app/src/main/java/com/hippo/reveal/ViewAnimationUtils.java delete mode 100644 app/src/main/java/io/codetail/animation/RevealAnimator.java delete mode 100644 app/src/main/java/io/codetail/animation/SupportAnimator.java delete mode 100644 app/src/main/java/io/codetail/animation/SupportAnimatorImpl.java delete mode 100644 app/src/main/java/io/codetail/animation/ViewAnimationUtils.java delete mode 100644 app/src/main/java/io/codetail/widget/RevealLinearLayout.java diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java index ed726dde1..aaee9184b 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java @@ -38,6 +38,7 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; +import com.hippo.reveal.ViewAnimationUtils; import com.hippo.easyrecyclerview.EasyRecyclerView; import com.hippo.easyrecyclerview.LinearDividerItemDecoration; import com.hippo.ehviewer.EhApplication; @@ -63,9 +64,6 @@ import com.hippo.yorozuya.LayoutUtils; import com.hippo.yorozuya.SimpleAnimatorListener; import com.hippo.yorozuya.ViewUtils; -import io.codetail.animation.SupportAnimator; -import io.codetail.animation.ViewAnimationUtils; - public final class GalleryCommentsScene extends ToolbarScene implements EasyRecyclerView.OnItemClickListener, EasyRecyclerView.OnItemLongClickListener, View.OnClickListener { @@ -276,12 +274,11 @@ public final class GalleryCommentsScene extends ToolbarScene mEditPanel.setVisibility(View.VISIBLE); int halfW = mEditPanel.getWidth() / 2; int halfH = mEditPanel.getHeight() / 2; - SupportAnimator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, 0, - (float) Math.hypot(halfW, halfH)); - animator.setDuration(300L); - animator.addListener(new SupportAnimator.SimpleAnimatorListener() { + Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, 0, + (float) Math.hypot(halfW, halfH)).setDuration(300L); + animator.addListener(new SimpleAnimatorListener() { @Override - public void onAnimationEnd() { + public void onAnimationEnd(Animator a) { mInAnimation = false; } }); @@ -311,12 +308,11 @@ public final class GalleryCommentsScene extends ToolbarScene mInAnimation = true; int halfW = mEditPanel.getWidth() / 2; int halfH = mEditPanel.getHeight() / 2; - SupportAnimator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, - (float) Math.hypot(halfW, halfH), 0.0f); - animator.setDuration(300L); - animator.addListener(new SupportAnimator.SimpleAnimatorListener() { + Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, + (float) Math.hypot(halfW, halfH), 0.0f).setDuration(300L); + animator.addListener(new SimpleAnimatorListener() { @Override - public void onAnimationEnd() { + public void onAnimationEnd(Animator a) { mEditPanel.setVisibility(View.GONE); mFab.setVisibility(View.VISIBLE); int fabStartX = mEditPanel.getLeft() + (mEditPanel.getWidth() / 2) - (mFab.getWidth() / 2); diff --git a/app/src/main/java/com/hippo/reveal/Reveal.java b/app/src/main/java/com/hippo/reveal/Reveal.java new file mode 100644 index 000000000..91124cda7 --- /dev/null +++ b/app/src/main/java/com/hippo/reveal/Reveal.java @@ -0,0 +1,24 @@ +/* + * Copyright 2016 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.reveal; + +public interface Reveal { + + void setRevealEnable(boolean enable); + + void setReveal(int centerX, int centerY, float radius); +} diff --git a/app/src/main/java/com/hippo/reveal/RevealLinearLayout.java b/app/src/main/java/com/hippo/reveal/RevealLinearLayout.java new file mode 100644 index 000000000..f7c938419 --- /dev/null +++ b/app/src/main/java/com/hippo/reveal/RevealLinearLayout.java @@ -0,0 +1,87 @@ +/* + * Copyright 2016 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.reveal; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Path; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +public class RevealLinearLayout extends LinearLayout implements Reveal { + + private final Path mRevealPath = new Path(); + private boolean mReveal; + private int mCenterX; + private int mCenterY; + private float mRadius; + + public RevealLinearLayout(Context context) { + super(context); + init(); + } + + public RevealLinearLayout(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public RevealLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + private void init() { + if (!ViewAnimationUtils.API_SUPPORT_CIRCULAR_REVEAL) { + setWillNotDraw(false); + } + } + + @Override + public void setRevealEnable(boolean enable) { + mReveal = enable; + invalidate(); + } + + @Override + public void setReveal(int centerX, int centerY, float radius) { + mCenterX = centerX; + mCenterY = centerY; + mRadius = radius; + invalidate(); + } + + @Override + public void draw(Canvas canvas) { + boolean reveal = mReveal; + int saveCount = 0; + + if (reveal) { + saveCount = canvas.save(); + Path path = mRevealPath; + path.reset(); + path.addCircle(mCenterX, mCenterY, mRadius, Path.Direction.CW); + canvas.clipPath(path); + } + + super.draw(canvas); + + if (reveal) { + canvas.restoreToCount(saveCount); + } + } +} diff --git a/app/src/main/java/com/hippo/reveal/ViewAnimationUtils.java b/app/src/main/java/com/hippo/reveal/ViewAnimationUtils.java new file mode 100644 index 000000000..118f5f8f1 --- /dev/null +++ b/app/src/main/java/com/hippo/reveal/ViewAnimationUtils.java @@ -0,0 +1,107 @@ +/* + * Copyright 2016 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.reveal; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.annotation.TargetApi; +import android.os.Build; +import android.view.View; + +import com.hippo.yorozuya.SimpleAnimatorListener; + +public final class ViewAnimationUtils { + private ViewAnimationUtils() {} + + public static final boolean API_SUPPORT_CIRCULAR_REVEAL = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; + // http://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported + public static final boolean API_SUPPORT_CANVAS_CLIP_PATH = + Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2; + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public static Animator createCircularReveal(View view, + int centerX, int centerY, float startRadius, float endRadius) { + if (API_SUPPORT_CIRCULAR_REVEAL) { + return android.view.ViewAnimationUtils.createCircularReveal( + view, centerX, centerY, startRadius, endRadius); + } else if (view instanceof Reveal){ + return createRevealAnimator((Reveal) view, centerX, centerY, + startRadius, endRadius); + } else { + throw new IllegalStateException("Only View implements CircularReveal or" + + " api >= 21 can create circular reveal"); + } + } + + private static Animator createRevealAnimator(Reveal reveal, int centerX, int centerY, + float startRadius, float endRadius) { + ValueAnimator animator = ValueAnimator.ofFloat(startRadius, endRadius); + animator.addUpdateListener(new RevealAnimatorUpdateListener(reveal, centerX, centerY)); + animator.addListener(new RevealAnimatorListener(reveal)); + return animator; + } + + private static class RevealAnimatorUpdateListener + implements ValueAnimator.AnimatorUpdateListener { + + private final Reveal mReveal; + private final int mCenterX; + private final int mCenterY; + + public RevealAnimatorUpdateListener(Reveal reveal, int centerX, int centerY) { + mReveal = reveal; + mCenterX = centerX; + mCenterY = centerY; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + Object value = animation.getAnimatedValue(); + if (value instanceof Float) { + mReveal.setReveal(mCenterX, mCenterY, (Float) value); + } + } + } + + private static class RevealAnimatorListener extends SimpleAnimatorListener { + + private final Reveal mReveal; + private final View mView; + + public RevealAnimatorListener(Reveal reveal) { + mReveal = reveal; + mView = (View) reveal; + } + + @Override + public void onAnimationStart(Animator animation) { + if (!API_SUPPORT_CANVAS_CLIP_PATH) { + mView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + } + mReveal.setRevealEnable(true); + } + + @Override + public void onAnimationEnd(Animator animation) { + mReveal.setRevealEnable(false); + if (!API_SUPPORT_CANVAS_CLIP_PATH) { + mView.setLayerType(View.LAYER_TYPE_NONE, null); + } + } + } +} diff --git a/app/src/main/java/io/codetail/animation/RevealAnimator.java b/app/src/main/java/io/codetail/animation/RevealAnimator.java deleted file mode 100644 index 4624337e0..000000000 --- a/app/src/main/java/io/codetail/animation/RevealAnimator.java +++ /dev/null @@ -1,147 +0,0 @@ -package io.codetail.animation; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.graphics.Rect; -import android.util.Property; -import android.view.View; - -import java.lang.ref.WeakReference; - -/** - * @hide - */ -public interface RevealAnimator{ - - RevealRadius CLIP_RADIUS = new RevealRadius(); - - /** - * Listen when animation start/end/cancel - * and setup view for it - */ - void onRevealAnimationStart(); - void onRevealAnimationEnd(); - void onRevealAnimationCancel(); - - /** - * Used with animator to animate view clipping - * - * @param value clip radius - */ - void setRevealRadius(float value); - - /** - * Used with animator to animate view clipping - * - * @return current radius - */ - float getRevealRadius(); - - /** - * Invalidate certain rectangle - * - * @param bounds bounds to redraw - * @see View#invalidate(Rect) - */ - void invalidate(Rect bounds); - - /** - * {@link ViewAnimationUtils#createCircularReveal(View, int, int, float, float)} is - * called it creates new {@link io.codetail.animation.RevealAnimator.RevealInfo} - * and attaches to parent, here is necessary data about animation - * - * @param info reveal information - * - * @see RevealAnimator.RevealInfo - */ - void attachRevealInfo(RevealInfo info); - - /** - * Returns new {@link SupportAnimator} that plays - * reversed animation of current one - * - * This method might be temporary, you should call - * {@link SupportAnimator#reverse()} instead - * - * @hide - * @return reverse {@link SupportAnimator} - * - * @see SupportAnimator#reverse() - */ - SupportAnimator startReverseAnimation(); - - class RevealInfo{ - public final int centerX; - public final int centerY; - public final float startRadius; - public final float endRadius; - public final WeakReference target; - - public RevealInfo(int centerX, int centerY, float startRadius, float endRadius, - WeakReference target) { - this.centerX = centerX; - this.centerY = centerY; - this.startRadius = startRadius; - this.endRadius = endRadius; - this.target = target; - } - - public View getTarget(){ - return target.get(); - } - - public boolean hasTarget(){ - return getTarget() != null; - } - } - - class RevealFinishedIceCreamSandwich extends AnimatorListenerAdapter { - WeakReference mReference; - int mFeaturedLayerType; - int mLayerType; - - RevealFinishedIceCreamSandwich(RevealAnimator target, int layerType) { - mReference = new WeakReference<>(target); - mLayerType = ((View) target).getLayerType(); - mFeaturedLayerType = layerType; - } - - @Override - public void onAnimationStart(Animator animation) { - RevealAnimator target = mReference.get(); - ((View) target).setLayerType(mFeaturedLayerType, null); - target.onRevealAnimationStart(); - } - - @Override - public void onAnimationCancel(Animator animation) { - RevealAnimator target = mReference.get(); - ((View) target).setLayerType(mLayerType, null); - target.onRevealAnimationCancel(); - } - - @Override - public void onAnimationEnd(Animator animation) { - RevealAnimator target = mReference.get(); - ((View) target).setLayerType(mLayerType, null); - target.onRevealAnimationEnd(); - } - } - - class RevealRadius extends Property { - - public RevealRadius() { - super(Float.class, "revealRadius"); - } - - @Override - public void set(RevealAnimator object, Float value) { - object.setRevealRadius(value); - } - - @Override - public Float get(RevealAnimator object) { - return object.getRevealRadius(); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/io/codetail/animation/SupportAnimator.java b/app/src/main/java/io/codetail/animation/SupportAnimator.java deleted file mode 100644 index b9b8e30dd..000000000 --- a/app/src/main/java/io/codetail/animation/SupportAnimator.java +++ /dev/null @@ -1,186 +0,0 @@ -package io.codetail.animation; - -import android.animation.Animator; - -import java.lang.ref.WeakReference; - -public abstract class SupportAnimator extends Animator{ - - WeakReference mTarget; - - public SupportAnimator(RevealAnimator target) { - mTarget = new WeakReference<>(target); - } - - /** - * @return true if using native android animation framework, otherwise is - * nineoldandroids - */ - public abstract boolean isNativeAnimator(); - - /** - * @return depends from {@link android.os.Build.VERSION} if sdk version - * {@link android.os.Build.VERSION_CODES#LOLLIPOP} and greater will return - * {@link android.animation.Animator} - */ - public abstract Object get(); - - /** - * Starts this animation. If the animation has a nonzero startDelay, the animation will start - * running after that delay elapses. A non-delayed animation will have its initial - * value(s) set immediately, followed by calls to - * {@link android.animation.Animator.AnimatorListener#onAnimationStart(android.animation.Animator)} - * for any listeners of this animator. - * - *

The animation started by calling this method will be run on the thread that called - * this method. This thread should have a Looper on it (a runtime exception will be thrown if - * this is not the case). Also, if the animation will animate - * properties of objects in the view hierarchy, then the calling thread should be the UI - * thread for that view hierarchy.

- * - */ - @Override - public abstract void start(); - - - /** - * Adds a listener to the set of listeners that are sent events through the life of an - * animation, such as start, repeat, and end. - * - * @param listener the listener to be added to the current set of listeners for this animation. - */ - public abstract void addListener(AnimatorListener listener); - - - /** - * Returns whether this Animator is currently running (having been started and gone past any - * initial startDelay period and not yet ended). - * - * @return Whether the Animator is running. - */ - @Override - public abstract boolean isRunning(); - - - /** - * Cancels the animation. Unlike {@link #end()}, cancel() causes the animation to - * stop in its tracks, sending an - * {@link AnimatorListener#onAnimationCancel()} to - * its listeners, followed by an - * {@link AnimatorListener#onAnimationEnd()} message. - * - *

This method must be called on the thread that is running the animation.

- */ - @Override - public abstract void cancel(); - - /** - * Ends the animation. This causes the animation to assign the end value of the property being - * animated, then calling the - * {@link AnimatorListener#onAnimationEnd()} method on - * its listeners. - * - *

This method must be called on the thread that is running the animation.

- */ - @Override - public void end() { - } - - /** - * This method tells the object to use appropriate information to extract - * starting values for the animation. For example, a AnimatorSet object will pass - * this call to its child objects to tell them to set up the values. A - * ObjectAnimator object will use the information it has about its target object - * and PropertyValuesHolder objects to get the start values for its properties. - * A ValueAnimator object will ignore the request since it does not have enough - * information (such as a target object) to gather these values. - */ - @Override - public void setupStartValues() { - } - - /** - * This method tells the object to use appropriate information to extract - * ending values for the animation. For example, a AnimatorSet object will pass - * this call to its child objects to tell them to set up the values. A - * ObjectAnimator object will use the information it has about its target object - * and PropertyValuesHolder objects to get the start values for its properties. - * A ValueAnimator object will ignore the request since it does not have enough - * information (such as a target object) to gather these values. - */ - @Override - public void setupEndValues() { - } - - /** - * Experimental feature - */ - public SupportAnimator reverse() { - if(isRunning()){ - return null; - } - - RevealAnimator target = mTarget.get(); - if(target != null){ - return target.startReverseAnimation(); - } - - return null; - } - - /** - *

An animation listener receives notifications from an animation. - * Notifications indicate animation related events, such as the end or the - * repetition of the animation.

- */ - public interface AnimatorListener { - /** - *

Notifies the start of the animation.

- */ - void onAnimationStart(); - - /** - *

Notifies the end of the animation. This callback is not invoked - * for animations with repeat count set to INFINITE.

- */ - void onAnimationEnd(); - - /** - *

Notifies the cancellation of the animation. This callback is not invoked - * for animations with repeat count set to INFINITE.

- */ - void onAnimationCancel(); - - /** - *

Notifies the repetition of the animation.

- */ - void onAnimationRepeat(); - } - - /** - *

Provides default implementation for AnimatorListener.

- */ - public static abstract class SimpleAnimatorListener implements AnimatorListener { - - @Override - public void onAnimationStart() { - - } - - @Override - public void onAnimationEnd() { - - } - - @Override - public void onAnimationCancel() { - - } - - @Override - public void onAnimationRepeat() { - - } - } - -} diff --git a/app/src/main/java/io/codetail/animation/SupportAnimatorImpl.java b/app/src/main/java/io/codetail/animation/SupportAnimatorImpl.java deleted file mode 100644 index de0214ca3..000000000 --- a/app/src/main/java/io/codetail/animation/SupportAnimatorImpl.java +++ /dev/null @@ -1,154 +0,0 @@ -package io.codetail.animation; - -import android.animation.Animator; -import android.animation.TimeInterpolator; -import android.annotation.TargetApi; -import android.os.Build; - -import java.lang.ref.WeakReference; - -@TargetApi(Build.VERSION_CODES.HONEYCOMB) -final class SupportAnimatorImpl extends SupportAnimator{ - - WeakReference mAnimator; - - SupportAnimatorImpl(Animator animator, RevealAnimator target) { - super(target); - mAnimator = new WeakReference<>(animator); - } - - @Override - public boolean isNativeAnimator() { - return true; - } - - @Override - public Object get() { - return mAnimator.get(); - } - - - @Override - public void start() { - Animator a = mAnimator.get(); - if(a != null) { - a.start(); - } - } - - @Override - public Animator setDuration(long duration) { - Animator a = mAnimator.get(); - if(a != null) { - a.setDuration(duration); - } - return this; - } - - @Override - public void setInterpolator(TimeInterpolator value) { - Animator a = mAnimator.get(); - if(a != null) { - a.setInterpolator(value); - } - } - - @Override - public void addListener(final AnimatorListener listener) { - Animator a = mAnimator.get(); - if(a == null) { - return; - } - - if(listener == null){ - a.addListener(null); - return; - } - - a.addListener(new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) { - listener.onAnimationStart(); - } - - @Override - public void onAnimationEnd(Animator animation) { - listener.onAnimationEnd(); - } - - @Override - public void onAnimationCancel(Animator animation) { - listener.onAnimationCancel(); - } - - @Override - public void onAnimationRepeat(Animator animation) { - listener.onAnimationRepeat(); - } - }); - } - - @Override - public boolean isRunning() { - Animator a = mAnimator.get(); - return a != null && a.isRunning(); - } - - @Override - public void cancel() { - Animator a = mAnimator.get(); - if(a != null){ - a.cancel(); - } - } - - @Override - public void end() { - Animator a = mAnimator.get(); - if(a != null){ - a.end(); - } - } - - @Override - public long getStartDelay() { - Animator a = mAnimator.get(); - if(a != null){ - return a.getStartDelay(); - } - return 0; - } - - @Override - public void setStartDelay(long startDelay) { - Animator a = mAnimator.get(); - if(a != null){ - a.setStartDelay(startDelay); - } - } - - @Override - public long getDuration() { - Animator a = mAnimator.get(); - if(a != null){ - return a.getDuration(); - } - return 0; - } - - @Override - public void setupStartValues() { - Animator a = mAnimator.get(); - if(a != null){ - a.setupStartValues(); - } - } - - @Override - public void setupEndValues() { - Animator a = mAnimator.get(); - if(a != null){ - a.setupEndValues(); - } - } -} diff --git a/app/src/main/java/io/codetail/animation/ViewAnimationUtils.java b/app/src/main/java/io/codetail/animation/ViewAnimationUtils.java deleted file mode 100644 index 159c61fda..000000000 --- a/app/src/main/java/io/codetail/animation/ViewAnimationUtils.java +++ /dev/null @@ -1,157 +0,0 @@ -package io.codetail.animation; - -import android.animation.ObjectAnimator; -import android.annotation.TargetApi; -import android.os.Build; -import android.view.View; -import android.view.animation.AccelerateDecelerateInterpolator; - -import java.lang.ref.WeakReference; - -import io.codetail.animation.RevealAnimator.RevealInfo; - -import static android.os.Build.VERSION.SDK_INT; -import static android.os.Build.VERSION_CODES.LOLLIPOP; -import static io.codetail.animation.RevealAnimator.CLIP_RADIUS; - -public class ViewAnimationUtils { - - private final static boolean LOLLIPOP_PLUS = SDK_INT >= LOLLIPOP; - - public static final int SCALE_UP_DURATION = 500; - - /** - * Returns an Animator which can animate a clipping circle. - *

- * Any shadow cast by the View will respect the circular clip from this animator. - *

- * Only a single non-rectangular clip can be applied on a View at any time. - * Views clipped by a circular reveal animation take priority over - * {@link android.view.View#setClipToOutline(boolean) View Outline clipping}. - *

- * Note that the animation returned here is a one-shot animation. It cannot - * be re-used, and once started it cannot be paused or resumed. - * - * @param view The View will be clipped to the animating circle. - * @param centerX The x coordinate of the center of the animating circle. - * @param centerY The y coordinate of the center of the animating circle. - * @param startRadius The starting radius of the animating circle. - * @param endRadius The ending radius of the animating circle. - */ - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public static SupportAnimator createCircularReveal(View view, - int centerX, int centerY, - float startRadius, float endRadius) { - - return createCircularReveal(view, centerX, centerY, startRadius, endRadius, View.LAYER_TYPE_SOFTWARE); - } - - /** - * Returns an Animator which can animate a clipping circle. - *

- * Any shadow cast by the View will respect the circular clip from this animator. - *

- * Only a single non-rectangular clip can be applied on a View at any time. - * Views clipped by a circular reveal animation take priority over - * {@link android.view.View#setClipToOutline(boolean) View Outline clipping}. - *

- * Note that the animation returned here is a one-shot animation. It cannot - * be re-used, and once started it cannot be paused or resumed. - * - * @param view The View will be clipped to the animating circle. - * @param centerX The x coordinate of the center of the animating circle. - * @param centerY The y coordinate of the center of the animating circle. - * @param startRadius The starting radius of the animating circle. - * @param endRadius The ending radius of the animating circle. - * - * @param layerType View layer type {@link View#LAYER_TYPE_HARDWARE} or {@link View#LAYER_TYPE_SOFTWARE} - */ - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public static SupportAnimator createCircularReveal(View view, - int centerX, int centerY, - float startRadius, float endRadius, int layerType) { - - if(!(view instanceof RevealAnimator)){ - throw new IllegalArgumentException("View must be inside RevealFrameLayout or RevealLinearLayout."); - } - - RevealAnimator revealLayout = (RevealAnimator) view; - revealLayout.attachRevealInfo(new RevealInfo(centerX, centerY, startRadius, endRadius, - new WeakReference<>(view))); - - if(LOLLIPOP_PLUS){ - return new SupportAnimatorImpl(android.view.ViewAnimationUtils - .createCircularReveal(view, centerX, centerY, startRadius, endRadius), revealLayout); - } - - ObjectAnimator reveal = ObjectAnimator.ofFloat(revealLayout, CLIP_RADIUS, startRadius, endRadius); - reveal.addListener(new RevealAnimator.RevealFinishedIceCreamSandwich(revealLayout, layerType)); - return new SupportAnimatorImpl(reveal, revealLayout); - } - - /** - * Lifting view - * - * @param view The animation target - * @param baseRotation initial Rotation X in 3D space - * @param fromY initial Y position of view - * @param duration aniamtion duration - * @param startDelay start delay before animation begin - */ - @Deprecated - public static void liftingFromBottom(View view, float baseRotation, float fromY, int duration, int startDelay){ - view.setRotationX(baseRotation); - view.setTranslationY(fromY); - - view.animate() - .setInterpolator(new AccelerateDecelerateInterpolator()) - .setDuration(duration) - .setStartDelay(startDelay) - .rotationX(0) - .translationY(0) - .start(); - - } - - /** - * Lifting view - * - * @param view The animation target - * @param baseRotation initial Rotation X in 3D space - * @param duration aniamtion duration - * @param startDelay start delay before animation begin - */ - @Deprecated - public static void liftingFromBottom(View view, float baseRotation, int duration, int startDelay){ - view.setRotationX(baseRotation); - view.setTranslationY(view.getHeight() / 3); - - view.animate().setInterpolator(new AccelerateDecelerateInterpolator()) - .setDuration(duration) - .setStartDelay(startDelay) - .rotationX(0) - .translationY(0) - .start(); - - } - - /** - * Lifting view - * - * @param view The animation target - * @param baseRotation initial Rotation X in 3D space - * @param duration aniamtion duration - */ - @Deprecated - public static void liftingFromBottom(View view, float baseRotation, int duration){ - view.setRotationX(baseRotation); - view.setTranslationY(view.getHeight() / 3); - - view.animate().setInterpolator(new AccelerateDecelerateInterpolator()) - .setDuration(duration) - .rotationX(0) - .translationY(0) - .start(); - - } -} diff --git a/app/src/main/java/io/codetail/widget/RevealLinearLayout.java b/app/src/main/java/io/codetail/widget/RevealLinearLayout.java deleted file mode 100644 index ab785460e..000000000 --- a/app/src/main/java/io/codetail/widget/RevealLinearLayout.java +++ /dev/null @@ -1,115 +0,0 @@ -package io.codetail.widget; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Path; -import android.graphics.Rect; -import android.util.AttributeSet; -import android.view.View; -import android.widget.LinearLayout; - -import io.codetail.animation.RevealAnimator; -import io.codetail.animation.SupportAnimator; -import io.codetail.animation.ViewAnimationUtils; - -public class RevealLinearLayout extends LinearLayout implements RevealAnimator{ - - private final Path mRevealPath; - private final Rect mTargetBounds = new Rect(); - private RevealInfo mRevealInfo; - private boolean mRunning; - private float mRadius; - - public RevealLinearLayout(Context context) { - this(context, null); - } - - public RevealLinearLayout(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public RevealLinearLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs); - mRevealPath = new Path(); - } - - @Override - public void onRevealAnimationStart() { - mRunning = true; - } - - @Override - public void onRevealAnimationEnd() { - mRunning = false; - invalidate(mTargetBounds); - } - - @Override - public void onRevealAnimationCancel() { - onRevealAnimationEnd(); - } - - /** - * Circle radius size - * - * @hide - */ - @Override - public void setRevealRadius(float radius){ - mRadius = radius; - mRevealInfo.getTarget().getHitRect(mTargetBounds); - invalidate(mTargetBounds); - } - - /** - * Circle radius size - * - * @hide - */ - @Override - public float getRevealRadius(){ - return mRadius; - } - - /** - * @hide - */ - @Override - public void attachRevealInfo(RevealInfo info) { - mRevealInfo = info; - } - - /** - * @hide - */ - @Override - public SupportAnimator startReverseAnimation() { - if(mRevealInfo != null && mRevealInfo.hasTarget() && !mRunning) { - return ViewAnimationUtils.createCircularReveal(mRevealInfo.getTarget(), - mRevealInfo.centerX, mRevealInfo.centerY, - mRevealInfo.endRadius, mRevealInfo.startRadius); - } - return null; - } - - @Override - protected boolean drawChild(Canvas canvas, View child, long drawingTime) { - if(mRunning && child == mRevealInfo.getTarget()){ - final int state = canvas.save(); - - mRevealPath.reset(); - mRevealPath.addCircle(mRevealInfo.centerX, mRevealInfo.centerY, mRadius, Path.Direction.CW); - - canvas.clipPath(mRevealPath); - - boolean isInvalided = super.drawChild(canvas, child, drawingTime); - - canvas.restoreToCount(state); - - return isInvalided; - } - - return super.drawChild(canvas, child, drawingTime); - } - -} diff --git a/app/src/main/res/layout/scene_gallery_comments.xml b/app/src/main/res/layout/scene_gallery_comments.xml index 6c7f5bcb1..e01ae0106 100644 --- a/app/src/main/res/layout/scene_gallery_comments.xml +++ b/app/src/main/res/layout/scene_gallery_comments.xml @@ -38,7 +38,7 @@ android:text="@string/no_one_comments_gallery" style="@style/TextAppearance.AppCompat.Medium"/> - - +