Android实现花瓣飘落效果

龙旋

共 5593字,需浏览 12分钟

 ·

2021-05-01 21:42

效果展示



实现原理

  • 首先需要生成绘制小花的坐标点,坐标点的横坐标是根据控件的宽度随机生成的,而纵坐标则设置为小花图片高度的负值(这样可以实现小花从屏幕外进入)。


  • 将这些点存储到集合当中。


  • 遍历集合根据点的位置绘制小花


  • 绘制完后不断增加各个点的纵坐标



实现步骤

1.定义变量将变量初始化

    private SurfaceHolder mHolder;    private boolean mFlag = true;//绘制小花线程的开关标志    private ArrayList<PointF> mFlowers;//小花点的坐标集合    private Random mRandom;//负责随机数生成    private Bitmap mBitmap;//小花的图案
public FlowerView(Context context) { super(context); init(); }
public FlowerView(Context context, AttributeSet attrs) { super(context, attrs); init(); }
public FlowerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ mHolder = getHolder(); mHolder.addCallback(this); //设置背景透明 this.setZOrderOnTop(true); mHolder.setFormat(PixelFormat.TRANSLUCENT);
mFlowers = new ArrayList<>(); mRandom = new Random();
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_hua);
}


2.实现添加花朵坐标点的方法

/**     * 添加花朵     */    private void addFlower(){        PointF point = new PointF();        point.x=mRandom.nextInt(getWidth());//根据控件宽度随机生成X轴坐标        point.y=-mBitmap.getHeight();//纵坐标设置为小花图像的负值(产生从屏幕外进入的效果)        mFlowers.add(point);//将坐标点添加进集合    }


3.实现SurfaceHolder.Callback及Runnable接口

public class FlowerView extends SurfaceView implements SurfaceHolder.Callback,Runnable


4.在run方法中实现绘制逻辑

 @Override    public void run() {        while (mFlag){            try {                Thread.sleep(80);//控制小花的下落速度                Canvas canvas = mHolder.lockCanvas();                PointF pointF = null;                //清屏操作(否则会残留一些无用图像)                if(canvas!=null){                    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);                }else {                    continue;                }                for(PointF point: mFlowers){                    pointF = point;                    canvas.drawBitmap(mBitmap,pointF.x,pointF.y,null);                    int i = mRandom.nextInt(getHeight()/50)+getHeight()/50;//修改雨滴线的纵坐标,使其看起来在下雨                    pointF.y=pointF.y+i;                }                mHolder.unlockCanvasAndPost(canvas);                addFlower();                //当绘制点的纵坐标大于控件高度时,将该点移除                if(mFlowers.size()>0&&pointF!=null&&pointF.y>=getHeight()){                    mFlowers.remove(pointF);                }
}catch (Exception e){} } }


5.在SurfaceHolder.Callback的回调方法中开启绘制线程

 @Override    public void surfaceCreated(SurfaceHolder holder) {        mFlag = true;//surface创建时将线程开关打开        new Thread(this).start();//开启线程绘制    }
@Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mFlowers.clear();//当控件发生改变时清除之前的绘制点 }
@Override public void surfaceDestroyed(SurfaceHolder holder) { mFlag = false;//当surface销毁时关掉绘制线程 }


完整代码展示

public class FlowerView extends SurfaceView implements SurfaceHolder.Callback,Runnable{    private SurfaceHolder mHolder;    private boolean mFlag = true;//绘制小花线程的开关标志    private ArrayList<PointF> mFlowers;//小花点的坐标集合    private Random mRandom;//负责随机数生成    private Bitmap mBitmap;//小花的图案
public FlowerView(Context context) { super(context); init(); }
public FlowerView(Context context, AttributeSet attrs) { super(context, attrs); init(); }
public FlowerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ mHolder = getHolder(); mHolder.addCallback(this); //设置背景透明 this.setZOrderOnTop(true); mHolder.setFormat(PixelFormat.TRANSLUCENT);
mFlowers = new ArrayList<>(); mRandom = new Random();
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_hua);
}
@Override public void surfaceCreated(SurfaceHolder holder) { mFlag = true; new Thread(this).start(); }
@Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mFlowers.clear(); }
@Override public void surfaceDestroyed(SurfaceHolder holder) { mFlag = false; }
@Override public void run() { while (mFlag){ try { Thread.sleep(80); Canvas canvas = mHolder.lockCanvas(); PointF pointF = null; //清屏操作 if(canvas!=null){ canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); }else { continue; } for(PointF point: mFlowers){ pointF = point; canvas.drawBitmap(mBitmap,pointF.x,pointF.y,null); int i = mRandom.nextInt(getHeight()/50)+getHeight()/50;//修改雨滴线的纵坐标,使其看起来在下雨 pointF.y=pointF.y+i; } mHolder.unlockCanvasAndPost(canvas); addFlower(); if(mFlowers.size()>0&&pointF!=null&&pointF.y>=getHeight()){ mFlowers.remove(pointF); }
}catch (Exception e){} } }
/** * 添加花朵 */ private void addFlower(){ PointF point = new PointF(); point.x=mRandom.nextInt(getWidth()); point.y=-mBitmap.getHeight(); mFlowers.add(point); }}


到这里就结束啦.
浏览 114
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报