Skip to content

Instantly share code, notes, and snippets.

@hegazy
Forked from nhaarman/semi-ripple.java
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hegazy/b1f8b2405f64908db8e9 to your computer and use it in GitHub Desktop.
Save hegazy/b1f8b2405f64908db8e9 to your computer and use it in GitHub Desktop.
Riiple Effect in Button onClickListener
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);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment