今天看了网上的一个叫潭州学院的课程里的一个自定义View水波纹效果的视频。感觉效果不错,看完之后自己敲了一遍。
先看一下效果
以前也曾想过做个类似的效果,但最终只是实现了一个的效果,多了的话怎么办呢,视频中提供了一个非常好的方法。根据面向对象的思想,将每个wave看成一个对象
定义一个类:
class Wave {
Paint p;
int radius;
int x;
int y;
int alpha;
}
在成员变量中有一个Wave类的list 保存在内存中。 在onTouchEvent()方法中添加一个一个的wave:
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int cx = (int) event.getX();
int cy = (int) event.getY();
addPoint(cx,cy);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
添加完之后使用handler发一个消息,在handleMessage方法中把list中的wave一个个的取出来之后改变其变量中的半径的值和透明度的值,然后重新绘制:
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
changeData();
invalidate();
mHandler.sendEmptyMessageDelayed(0,50);
}
};
handleMessage中必须在调用setEmptyMessage方法才能让其循环起来一直增长。最后当透明度的值小于0的时候把list中的当前wave移除掉。
全部代码:
package com.chs.test.widget;
import android.content.Context;
import android.content.res.Resources;
import android.gesture.GestureStroke;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.chs.test.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 作者:chs on 2016/1/13 15:00
* 邮箱:657083984@qq.com
*/
public class MyTestView extends View {
private List<Wave> waves ;
private boolean isRunning = false;
private int[]mColors = new int[]{Color.BLUE,Color.CYAN,Color.GRAY,Color.GREEN,Color.RED,Color.YELLOW};
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
changeData();
invalidate();
mHandler.sendEmptyMessageDelayed(0,50);
}
};
private void changeData() {
for(int i = 0;i<waves.size();i++){
Wave wave = waves.get(i);
wave.radius+=10;
wave.alpha-=5;
wave.p.setAlpha(wave.alpha);
if(wave.alpha<0){
waves.remove(i);
}
}
if(waves.size()==0){
isRunning = false;
}
}
public MyTestView(Context context) {
this(context, null);
}
public MyTestView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyTestView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initData();
}
class Wave {
Paint p;
int radius;
int x;
int y;
int alpha;
}
private void initData() {
waves = new ArrayList<>();
}
@Override
protected void onDraw(Canvas canvas) {
for(int i = 0;i<waves.size();i++){
Wave wave = waves.get(i);
canvas.drawCircle(wave.x,wave.y,wave.radius,wave.p);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int cx = (int) event.getX();
int cy = (int) event.getY();
addPoint(cx,cy);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
private void addPoint(int cx, int cy) {
if(waves.size()==0){
createPoint(cx, cy);
isRunning = true;
mHandler.sendEmptyMessage(0);
}else {
createPoint(cx, cy);
}
}
private void createPoint(int cx, int cy) {
Wave wave = new Wave();
wave.x = cx;
wave.y = cy;
wave.radius = 10;
wave.alpha = 255;
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(mColors[(int) (Math.random() * 6)]);
paint.setStrokeWidth(20);
wave.p = paint;
waves.add(wave);
}
}