20180509_183307.gif安卓SurfaceView 实现下雨效果 先来一张效果图
我的思路:下雨每个雨滴用一条线来实现,生成一条线,X轴坐标随机,Y轴不断增加,就形成了下雨的效果
1.首先定义mSurfaceView类,继承Serfaceview 并实现SurfaceHolder.Callbac以及Runnable接口
public class mSurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Flag=false;
}
@Override
public void run() { }
}
2.定义如下成员变量
//用于标注线程是否继续
private boolean Flag=true;
//SurfaceHolder
SurfaceHolder surfaceHolder;
//定义画笔
Paint paint=new Paint();
//雨滴的集合
public List<Line> lines=new ArrayList<>();
//Random对象 用于随机生成雨滴的X轴坐标
Random random=new Random();
3.实现构造方法,此处注意,构造方法用两个参数的
public mSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
surfaceHolder=getHolder();
surfaceHolder.addCallback(this);
//设置背景透明
this.setZOrderOnTop(true);
surfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
}
4.实现init方法 用于初始化画笔等操作
private void init() {
//设置画笔颜色
paint.setColor(Color.WHITE);
//抗锯齿
paint.setAntiAlias(true);
//设置画笔颜色
paint.setColor(Color.WHITE);
//设置画笔模式为填充
paint.setStyle(Paint.Style.FILL);
//设置画笔宽度为2
paint.setStrokeWidth(2f);
}
定义雨滴的类
前面说过,每个雨滴都是一条线 那么下面咱们实现雨滴的类:Line
//雨的类,每一条线代表一个雨滴
class Line{
private int startx;//线的起始X坐标
private int starty;//线的起始Y坐标
private int stopx;//线的结束X坐标
private int stopy;//线的结束Y坐标
public int getStartx() {
return startx;
}
public void setStartx(int startx) {
this.startx = startx;
}
public int getStarty() {
return starty;
}
public void setStarty(int starty) {
this.starty = starty;
}
public int getStopx() {
return stopx;
}
public void setStopx(int stopx) {
this.stopx = stopx;
}
public int getStopy() {
return stopy;
}
public void setStopy(int stopy) {
this.stopy = stopy;
}
}
每一条雨滴都是存在雨滴的集合内的,咱们需要实现添加雨滴的方法,生成雨滴并且把雨滴添加到集合中
//添加雨滴
private void addline() {
Line line=new Line();
//随机生成雨滴的起始X坐标
line.startx=random.nextInt(getWidth());
//设置雨滴的起始y坐标为-60 从屏幕外开始运动
line.starty=-60;
//雨滴偏移3个像素 看起来不会太直
line.stopx=line.getStartx()+3;
//雨滴的长度
line.stopy=line.starty+60;
//添加到集合
lines.add(line);
}
好了,准备工作做完了,下面实现开始实现Run方法,绘制每一条雨滴
@Override
public void run() {
Canvas canvas=null;
Line line=null;
while (Flag){
try {
canvas=surfaceHolder.lockCanvas();
//清空画布
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
}catch (Exception e){
break;
}
//遍历雨滴集合
for (int i = 0; i < lines.size(); i++) {
line=lines.get(i);
//绘制雨滴
canvas.drawLine(line.getStartx(),line.getStarty(),line.getStopx(),line.getStopy(),paint);
//绘制雨滴之后 更改雨滴的Y轴坐标 下次绘制时即可更新位置 使雨滴下落
//取三个随机数 每个随机数代表3种不同的长度以及下落速度
int c=random.nextInt(3);
if (c==0){
line.setStarty(line.getStarty()+20);
line.setStopy(line.getStarty()+40);
}
if (c==1){
line.setStarty(line.getStarty()+30);
line.setStopy(line.getStarty()+50);
}
if (c==2){
line.setStarty(line.getStarty()+15);
line.setStopy(line.getStarty()+30);
}
if (c==3){
line.setStarty(line.getStarty()+40);
line.setStopy(line.getStarty()+35);
}
}
//解锁画布
surfaceHolder.unlockCanvasAndPost(canvas);
//添加雨滴
addline();
//当雨滴大于100条时 删除第一个 让雨滴保持在100条
if (lines.size()>100){
lines.remove(0);
}
Log.d("log", "run: "+lines.size());
}
}
在surfaceCreated方法中启动线程:
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//初始化画笔等
init();
Flag=true;
//启动线程绘制雨滴
new Thread(this).start();
}
大工告成,在布局中添加:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:background="@mipmap/bg">
<maill.shop.com.volley.mtest.mSurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
github完整代码地址:SurfaceView实现下雨效果
csdn资源下载:安卓SurfaceView实现下雨效果源码
PS:如有不正确的地方欢迎指出!
转载请注明出处:安卓SurfaceView实现下雨效果源码
网友评论