Android水波纹效果
需要到水波纹效果的场景还蛮少的。万一刚好你需要呢
一、思路:
自定义组件SpreadView
二、效果图:
看视频更直观点:
Android轮子分享-水波纹效果
三、关键代码:
public class SpreadView extends View {
private Paint centerPaint; //中心圆paint
private int radius = 100; //中心圆半径 px
private Paint spreadPaint; //扩散圆paint
private float centerX;//圆心x
private float centerY;//圆心y
private int distance = 5; //每次圆递增间距 px
private int maxRadius; //扩散波纹圆最大半径 px
private int radiusDifference = 120; // 二个扩散圈之间距离差
private boolean isNeedCenter = false; // 是否需要绘画中心圆
private int delayMilliseconds = 25;//扩散延迟间隔,毫秒,越大扩散越慢
private List<Integer> spreadRadius = new ArrayList<>();//扩散圆层级数,元素为扩散的距离
private List<Integer> alphas = new ArrayList<>();//对应每层圆的透明度
private int alphaReduce ; //每次透明度减少量
private int spreadStartTransparency = 255; // 扩散波纹最开始的透明度,最大255为完全不透明
public SpreadView(Context context) {
this(context, null, 0);
}
public SpreadView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SpreadView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SpreadView, defStyleAttr, 0);
radius = a.getInt(R.styleable.SpreadView_spread_radius, radius);
maxRadius = a.getInt(R.styleable.SpreadView_spread_max_radius, getScreenWidth(getContext(),false)/2);
isNeedCenter = a.getBoolean(R.styleable.SpreadView_is_need_center, isNeedCenter);
int centerColor = a.getColor(R.styleable.SpreadView_spread_center_color, ContextCompat.getColor(context, R.color.c_main));
int spreadColor = a.getColor(R.styleable.SpreadView_spread_spread_color, ContextCompat.getColor(context, R.color.white));
distance = a.getInt(R.styleable.SpreadView_spread_distance, distance);
spreadStartTransparency = a.getInt(R.styleable.SpreadView_spread_start_transparency, spreadStartTransparency);
a.recycle();
if(isNeedCenter){
centerPaint = new Paint();
centerPaint.setColor(centerColor);
centerPaint.setAntiAlias(true);
}
alphas.add(spreadStartTransparency);
spreadRadius.add(0);
spreadPaint = new Paint();
spreadPaint.setAntiAlias(true);
spreadPaint.setAlpha(spreadStartTransparency);
spreadPaint.setColor(spreadColor);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//圆心位置
centerX = w / 2;
centerY = h / 2;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(alphaReduce == 0){
int num = (maxRadius - radius)/distance;
alphaReduce = num > 1 ? Math.max((spreadStartTransparency / (num - 1)), 1) : spreadStartTransparency;
}
for (int i = 0; i < spreadRadius.size(); i++) {
int alpha = alphas.get(i);
spreadPaint.setAlpha(alpha);
int width = spreadRadius.get(i);
//绘制扩散的圆
canvas.drawCircle(centerX, centerY, radius + width, spreadPaint);
//每次扩散圆半径递增,圆透明度递减
if (alpha > 0) {
alpha = alpha - alphaReduce > 0 ? alpha - alphaReduce : 1;
alphas.set(i, alpha);
spreadRadius.set(i, width + distance);
}
}
//当上一个扩散圆增加的半径达到此值时添加新扩散圆
if (spreadRadius.get(spreadRadius.size() - 1) > radiusDifference) {
spreadRadius.add(0);
alphas.add(spreadStartTransparency);
}
//删除最先绘制的圆,即最外层的圆
if (alphas.get(0) == 1) {
alphas.remove(0);
spreadRadius.remove(0);
}
//中间的圆
if(isNeedCenter){
canvas.drawCircle(centerX, centerY, radius, centerPaint);
}
四、项目demo源码结构图:
有问题或者需要完整源码demo的私信我,我每天都看私信的