Android自定义View实现水波纹效果

本篇博文介绍一个Android自定义View的案例,后续博文会接下自定义View的相关流程和绘制原理。通过自定义控件实现。触摸屏幕实现水波纹效果。
实现步骤
第1步.自定义MyWave继承View
public class MyWave extends View {
}

第2步.重写带两个参数的构造方法
public MyWave(Context context, AttributeSet attrs) {
super (context, attrs);
wList = new ArrayList<MyWave.Wave>();
}
第3步.重写onDraw方法,在onDraw方法里根据水波纹集合mList,利用canvas.drawCircle方法绘制水波纹。在drawCircle方法中分别传入水波
纹的横坐标,纵坐标,半径和画笔,其中画笔包括要绘制的水波纹宽度和画笔的颜色。这4个属性封装在Wave类中.onDraw方法每执行一次
,都会绘制每一时刻的水波纹状态。
@Override
protected void onDraw(Canvas canvas) {
for ( int i = 0 ; i < wList .size(); i++) {
Wave wave = wList .get(i);
canvas.drawCircle(wave. pointX , wave. pointY , wave. radius , wave. paint );
}
}


/**
* 定义一个水波浪
* @author afu
*/
private class Wave {
//圆心
int pointX ;
int pointY ;

//画笔
Paint paint ;
//半径
int radius ;
}
第4步.重写onTouchEvent方法,对触摸事件进行监听,监听MotionEvent.ACTION_MOVE事件,根据手指触摸的位置,添加水波纹到mList集合中
@Override
public boolean onTouchEvent(MotionEvent event) {
super .onTouchEvent(event);

switch (event.getAction()) {
case MotionEvent. ACTION_DOWN :
case MotionEvent. ACTION_MOVE :
//圆心
int x = ( int ) event.getX();
int y = ( int ) event.getY();

addPoint(x,y);

break ;

default :
break ;
}

return true ;

}
第5步.在addPoint方法中,首先判断是否第一次添加水波纹,若是第一次添加,则通过Handler启动绘制动画。若不是第一次,则取出最后一次添加的水波纹,判断手指到最后一个水波纹的距离是否大于临界值,若大于临界值则添加新的水波纹到mList集合中。否则不添加,避免同个位置出现两个水波纹。
/**
* 添加新的水波浪中心点
* @param x
* @param y
*/
private void addPoint( int x, int y) {
if ( wList .size() == 0 ){
addPoint2List(x,y);
/*
* 第一次启动动画
*/
isRunning = true ;
handler .sendEmptyMessage( 0 );
} else {
//取最后一个圆环
Wave w = wList .get( wList .size()- 1 );

if (Math. abs (w. pointX - x)> DIS_SOLP || Math. abs (w. pointY -y)> DIS_SOLP ){
addPoint2List(x,y);
}

};

}
第6步.在Handler中首先通过flushData方法中对水波纹集合数据进行更新,降低水波纹的透明度同时增加水波纹的半径。当水波纹的透明度为0的时候顺便将其中mList集合中移除,刷新mList水波纹集合数据,再 执行invalidate方法通知View回调onDraw方法对界面进行绘制。这样水波纹就会不断变大且透明度不断降低,最后消失。
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
//刷新数据
flushData();
//刷新页面
invalidate();
//循环动画
if ( isRunning ) {
handler .sendEmptyMessageDelayed( 0 , 50 );
}

};
};
/**
* 刷新数据
*/
private void flushData() {

for ( int i = 0 ; i < wList .size(); i++) {

Wave w = wList .get(i);

//如果透明度为 0 从集合中删除
int alpha = w. paint .getAlpha();
if (alpha == 0 ){
wList .remove(i); //删除i 以后,i的值应该再减1 否则会漏掉一个对象,不过,在此处影响不大,效果上看不出来。
continue ;
}

alpha-= 5 ;
if (alpha< 5 ){
alpha = 0 ;
}
//降低透明度
w. paint .setAlpha(alpha);

//扩大半径
w. radius = w. radius + 3 ;
//设置半径厚度
w. paint .setStrokeWidth(w. radius / 3 );
}

/*
* 如果集合被清空,就停止刷新动画
*/
if ( wList .size() == 0 ){
isRunning = false ;
}
}


第7步.最后在Activity的布局中添加MyWave即可
< com.example.administrator.waveview.MyWave
android :layout_width= "match_parent"
android :layout_height= "match_parent" />

效果图如下所示( 其中闪绿屏是gif图截屏软件GifCam的问题,程序在手机上运行不会出现绿屏的):

完整代码托管在Github上: https://github.com/HuangJinJie/WaveView  喜欢给个Star,谢谢

猜你喜欢

转载自blog.csdn.net/hjj378315764/article/details/79504301