前言
其实波纹效果特别简单,就是以手指触摸位置为中心,画一个逐渐变大的渐变圆
这里我们以Button为例,手写一个带波纹效果的Button
代码
package com.android.architecture;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.AccelerateInterpolator;
import androidx.appcompat.widget.AppCompatButton;
@SuppressWarnings("all")
public class RippleButton extends AppCompatButton {
Paint paint = new Paint();
float radius = 10;
ValueAnimator anim;
boolean inAnimation = false;
float rx;
float ry;
public RippleButton(Context context) {
this(context, null);
}
public RippleButton(Context context, AttributeSet attributeSet) {
this(context, attributeSet, 0);
}
public RippleButton(Context context, AttributeSet attributeSet, int style) {
super(context, attributeSet, style);
init(context, attributeSet);
}
protected void init(Context context, AttributeSet attributeSet) {
setLayerType(LAYER_TYPE_SOFTWARE, null);
//开启半径逐渐增大动画
anim = ValueAnimator.ofFloat(0, 1);
anim.setDuration(800);
anim.setInterpolator(new AccelerateInterpolator());
anim.addUpdateListener(animation -> {
float ratio = (float) animation.getAnimatedValue();
if (ratio == 0)
return;
radius = getMeasuredWidth() * ratio;
invalidate();
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
inAnimation = true;
rx = event.getX();
ry = event.getY();
radius = 0;
anim.start();
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
anim.end();
inAnimation = false;
rx = 0;
ry = 0;
radius = 0;
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
//画基类内容
super.onDraw(canvas);
//无动画
if (!inAnimation)
return;
//设置渐变
RadialGradient gradient = new RadialGradient(rx, ry, radius, 0x00000000, 0x22000000, Shader.TileMode.CLAMP);
paint.setShader(gradient);
//画渐变圆
canvas.drawCircle(rx, ry, radius, paint);
}
}
效果