|
package com.nhaarman.test; |
|
|
|
import android.animation.ObjectAnimator; |
|
import android.content.Context; |
|
import android.graphics.Canvas; |
|
import android.graphics.Color; |
|
import android.graphics.Paint; |
|
import android.graphics.Path; |
|
import android.graphics.RadialGradient; |
|
import android.graphics.Region; |
|
import android.graphics.Shader; |
|
import android.support.annotation.NonNull; |
|
import android.util.AttributeSet; |
|
import android.view.MotionEvent; |
|
import android.view.View; |
|
import android.view.View.OnClickListener; |
|
import android.view.animation.AccelerateInterpolator; |
|
import android.widget.Button; |
|
|
|
public class RippleButton extends Button implements OnClickListener { |
|
|
|
private float mDownX; |
|
private float mDownY; |
|
|
|
private float mRadius; |
|
|
|
private Paint mPaint; |
|
|
|
public RippleButton(final Context context) { |
|
super(context); |
|
init(); |
|
} |
|
|
|
public RippleButton(final Context context, final AttributeSet attrs) { |
|
super(context, attrs); |
|
init(); |
|
} |
|
|
|
public RippleButton(final Context context, final AttributeSet attrs, final int defStyle) { |
|
super(context, attrs, defStyle); |
|
init(); |
|
} |
|
|
|
private void init() { |
|
mPaint = new Paint(); |
|
mPaint.setAlpha(100); |
|
setOnClickListener(this); |
|
} |
|
|
|
@Override |
|
public boolean onTouchEvent(@NonNull final MotionEvent event) { |
|
if (event.getActionMasked() == MotionEvent.ACTION_UP) { |
|
mDownX = event.getX(); |
|
mDownY = event.getY(); |
|
} |
|
return super.onTouchEvent(event); |
|
} |
|
|
|
public void setRadius(final float radius) { |
|
mRadius = radius; |
|
if (mRadius > 0) { |
|
RadialGradient radialGradient = new RadialGradient( |
|
mDownX, |
|
mDownY, |
|
mRadius * 3, |
|
Color.TRANSPARENT, |
|
Color.BLACK, |
|
Shader.TileMode.MIRROR |
|
); |
|
mPaint.setShader(radialGradient); |
|
} |
|
invalidate(); |
|
} |
|
|
|
private Path mPath = new Path(); |
|
private Path mPath2 = new Path(); |
|
|
|
@Override |
|
protected void onDraw(@NonNull final Canvas canvas) { |
|
super.onDraw(canvas); |
|
|
|
mPath2.reset(); |
|
mPath2.addCircle(mDownX, mDownY, mRadius, Path.Direction.CW); |
|
|
|
canvas.clipPath(mPath2); |
|
|
|
mPath.reset(); |
|
mPath.addCircle(mDownX, mDownY, mRadius / 3, Path.Direction.CW); |
|
|
|
canvas.clipPath(mPath, Region.Op.DIFFERENCE); |
|
|
|
canvas.drawCircle(mDownX, mDownY, mRadius, mPaint); |
|
} |
|
@Override |
|
public void onClick(View arg0) { |
|
|
|
ObjectAnimator animator = ObjectAnimator.ofFloat(this, "radius", 0, |
|
getWidth() * 3.0f); |
|
animator.setInterpolator(new AccelerateInterpolator()); |
|
animator.setDuration(400); |
|
animator.start(); |
|
} |
|
@Override |
|
public void setOnClickListener(final OnClickListener l) { |
|
|
|
super.setOnClickListener(new OnClickListener() { |
|
|
|
@Override |
|
public void onClick(View v) { |
|
|
|
RippleButton.this.onClick(v); |
|
l.onClick(v); |
|
} |
|
}); |
|
} |
|
} |