package com.wangdaye.mysplash.common.ui.widget.rippleButton; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.support.annotation.ColorInt; import android.util.AttributeSet; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.Animation; import android.view.animation.Transformation; /** * Ripple view. * * This view can draw reveal animation for {@link RippleButton}. * * */ public class RippleView extends View { private Paint paint; private RippleAnim anim; private RippleAnimatingCallback callback; private int centerX; private int centerY; private int radius; private boolean drawing; private class RippleAnim extends Animation { private int startX; private int startY; private int endRadius; RippleAnim(int x, int y) { this.startX = x; this.startY = y; calcEndRadius(x, y); setDuration(200); setInterpolator(new AccelerateDecelerateInterpolator()); setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { // do nothing. } @Override public void onAnimationEnd(Animation animation) { setDrawing(false); if (callback != null) { callback.animationDone(); } } @Override public void onAnimationRepeat(Animation animation) { // do nothing. } }); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { setDrawData( startX, startY, (int) (endRadius * interpolatedTime)); invalidate(); } // data. private void calcEndRadius(int x, int y) { int[] radius = new int[] { (int) Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5) + 1, (int) Math.pow(Math.pow(getMeasuredWidth() - x, 2) + Math.pow(y, 2), 0.5) + 1, (int) Math.pow(Math.pow(x, 2) + Math.pow(getMeasuredHeight() - y, 2), 0.5) + 1, (int) Math.pow(Math.pow(getMeasuredWidth() - x, 2) + Math.pow(getMeasuredHeight() - y, 2), 0.5) + 1}; endRadius = radius[0]; for (int i = 1; i < radius.length; i ++) { if (radius[i] > endRadius) { endRadius = radius[i]; } } } } public RippleView(Context context) { super(context); this.initialize(); } public RippleView(Context context, AttributeSet attrs) { super(context, attrs); this.initialize(); } public RippleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.initialize(); } private void initialize() { setDrawing(false); setDrawData(0, 0, 0); this.paint = new Paint(); paint.setFlags(Paint.ANTI_ALIAS_FLAG); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.TRANSPARENT); } // draw. @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension( MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); } @Override protected void onDraw(Canvas canvas) { canvas.drawCircle(centerX, centerY, radius, paint); } // control. public void drawRipple(@ColorInt int color, int startX, int startY) { if (!isDrawing()) { setDrawing(true); if (anim != null) { anim.cancel(); } paint.setColor(color); anim = new RippleAnim(startX, startY); startAnimation(anim); } } public void setDrawing(boolean drawing) { this.drawing = drawing; } public boolean isDrawing() { return drawing; } private void setDrawData(int x, int y, int r) { this.centerX = x; this.centerY = y; this.radius = r; } public void setColor(@ColorInt int color) { this.paint.setColor(color); } // interface. public interface RippleAnimatingCallback { void animationDone(); } public void setRippleAnimatingCallback(RippleAnimatingCallback callback) { this.callback = callback; } }