Ripple2.gif
package com.wgp.customview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* 自定义view
* 水波纹
*
* 思路:
* 1.先可以画出一个
* 2.把每个点定义一个进行封装,半径、圆心坐标、画笔
* 3.定义集合,把每个点对象进行存放,for循环改变每个对象的属性值(半径、透明度等)
* 4.改变完后,通知onDraw()方法,绘制集合里所有的信息,就是我们看到的效果了
*/
public class RippleView extends View {
private int[] colors = new int[]{Color.RED, Color.BLUE, Color.YELLOW, Color.GREEN};
//存放所有在屏幕上触发的点
private List<Ripple> rippleList = new ArrayList<>();
private float DISTANCE = 10;//两个点距离要大于10个像素,防止太密集
public RippleView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
//测量view的大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
//布局view在父类中的位置
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
/**
* 绘制内容
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < rippleList.size(); i++) {
Ripple ripple = rippleList.get(i);
canvas.drawCircle(ripple.cx, ripple.cy, ripple.radius, ripple.paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://按下获得圆心坐标
case MotionEvent.ACTION_MOVE:
Ripple ripple;
if (rippleList.size() == 0) {//第一次点击
ripple = new Ripple();
ripple.cx = event.getX();
ripple.cy = event.getY();
initPaint(ripple);
rippleList.add(ripple);
handler.sendEmptyMessage(0);
} else {
Ripple prRipple = rippleList.get(rippleList.size() - 1);
//做个判断 如果是屏幕上移动的产生的点,密度比较大,这里判断每个点距离大于10个像素的才加入集合
if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (Math.abs(prRipple.cx - event.getX()) > DISTANCE || Math.abs(prRipple.cy - event.getY()) > DISTANCE) {
ripple = new Ripple();
ripple.cx = event.getX();
ripple.cy = event.getY();
initPaint(ripple);
rippleList.add(ripple);
}
}
ripple = new Ripple();
ripple.cx = event.getX();
ripple.cy = event.getY();
initPaint(ripple);
rippleList.add(ripple);
}
break;
}
return true;
}
private void initPaint(Ripple ripple) {
ripple.paint = new Paint();
ripple.paint.setColor(colors[(int) (Math.random() * colors.length)]);
ripple.paint.setAntiAlias(true);
ripple.paint.setStyle(Paint.Style.STROKE);
}
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
//循环所有的圆心,并改变属性值,圆的透明度为小于10的时候,移除该圆对象。
for (int i = 0; i < rippleList.size(); i++) {
Ripple ripple = rippleList.get(i);
ripple.radius += 20;
ripple.alpha -= 10;
ripple.paint.setStrokeWidth(ripple.radius / 3);
ripple.paint.setAlpha(ripple.alpha);
if (ripple.alpha <= 10) {
rippleList.remove(ripple);
}
}
//使当前试图无效,会重新调用onDraw()绘制试图
invalidate();
if (rippleList.size() != 0) {
handler.sendMessageDelayed(Message.obtain(), 50);
}
return false;
}
});
}
//圆环
class Ripple {
float cx;//圆心x坐标
float cy;//圆心y坐标
float radius = 0;//半径
int alpha = 255;//透明度
Paint paint;
}
网友评论