随着Material Design越来越流行,当然少不了Button的波纹效果这种需求,一开始我觉得这玩意儿应该挺麻烦的,但是找了些别人写的库来看了一下,发现也就那么回事,所以自己也自定义了一个RippleButton
主要就是监听 view的touch事件
直接上代码
public class RippleButton extends AppCompatButton {
private int mX;
private ObjectAnimator mAnimator;
private int mCurRadius = 0;
private RadialGradient mRadialGradient;
private Paint mPaint;
private float mDensity;
private Rect mRect;
private float mDownY;
public RippleButton(Context context) {
super(context);
init();
}
public RippleButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RippleButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
setLayerType(LAYER_TYPE_SOFTWARE,null);
mDensity = getContext().getResources().getDisplayMetrics().density;
mPaint = new Paint();
}
private int dp(int dp) {
return (int) (dp * mDensity + 0.5f);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mX != event.getX()) {
mX = (int) event.getX();
mRect = new Rect(getLeft(), getTop(), getRight(), getBottom());
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mDownY==0){
mDownY = event.getY();
}
setRadius(dp(60));
return true;
}else if (event.getAction() ==MotionEvent.ACTION_MOVE){
if (mAnimator != null && mAnimator.isRunning()) {
mAnimator.cancel();
}
if (!mRect.contains(
getLeft() + (int) event.getX(),
getTop() + (int) event.getY())) {
setRadius(0);
} else {
setRadius(dp(60));
}
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (mRect.contains(
getLeft() + (int) event.getX(),
getTop() + (int) event.getY())){
if (mAnimator != null && mAnimator.isRunning()) {
mAnimator.cancel();
}
if (mAnimator == null) {
mAnimator = ObjectAnimator.ofInt(this,"radius",dp(50), getWidth());
}
mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
mAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
setRadius(0);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
mAnimator.start();
}
}
return super.onTouchEvent(event);
}
public void setRadius(final int radius) {
mCurRadius = radius;
if (mCurRadius > 0) {
mRadialGradient = new RadialGradient(mX, mDownY, mCurRadius, Color.parseColor("#22000000"), Color.parseColor("#22000000"), Shader.TileMode.MIRROR);
mPaint.setShader(mRadialGradient);
}
postInvalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mX, mDownY, mCurRadius, mPaint);
}
}
这里是可以设置渐变效果的,好像自带的也没有,所以我也没有设置渐变效果
简单点理解就是根据不同的touch事件画圆就行了
效果如下