安卓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()+30); line.setStopy(line.getStarty()+50); } if (c==1){ line.setStarty(line.getStarty()+40); line.setStopy(line.getStarty()+60); } if (c==2){ line.setStarty(line.getStarty()+50); line.setStopy(line.getStarty()+40); } if (c==3){ line.setStarty(line.getStarty()+60); line.setStopy(line.getStarty()+45); } } //解锁画布 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:如有不正确的地方欢迎指出!
转载请注明出处:https://blog.csdn.net/weixin_41549915/article/details/80257734