Android实现花瓣飘落效果的步骤
作者:itfitness 发布时间:2021-11-23 17:16:44
标签:Android,花瓣,飘落
目录
效果展示
实现原理
实现步骤
完整代码展示
效果展示
实现原理
首先需要生成绘制小花的坐标点,坐标点的横坐标是根据控件的宽度随机生成的,而纵坐标则设置为小花图片高度的负值(这样可以实现小花从屏幕外进入)。
将这些点存储到集合当中。
遍历集合根据点的位置绘制小花
绘制完后不断增加各个点的纵坐标
实现步骤
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);
}
}
来源:https://mp.weixin.qq.com/s/msBLhJIZJoFbRgH90lz3rQ
0
投稿
猜你喜欢
- 在《Spring Boot Hello World》中介绍了一个简单的spring boot例子,体验了spring boot中的诸多特性,
- @Valid:@Valid注解用于校验,所属包为:javax.validation.Valid。① 首先需要在实体类的相应字段上添加用于充当
- 前言dynamic-tp是一个轻量级的动态线程池插件,它是一个基于配置中心的动态线程池,线程池的参数可以通过配置中心配置进行动态的修改,在配
- CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就
- 本文实例讲述了C#自定义繁体和简体字库实现中文繁体和简体之间转换的方法。分享给大家供大家参考。具体分析如下:这里使用C#自定义繁体和简体字库
- 在java中常常会遇到这样一个问题,在实际应用中,总会碰到对List排序并过滤重复的问题,如果List中放的只是简单的String类型过滤s
- 一 关键pom<dependencies> <dependency> <groupId>or
- 前言话不多说,直接上图:笔者使用 RecyclerView 的 ItemTouchHelper 来实现这个效果,过程非常简单。为了学习,这里
- 以下是介绍利用List的subList方法实现对List分页,废话不多说了,直接看代码把/** *//** * List分页 &
- 目录前言错误实例演示实现ApplicationContextAware接口lookup methodlookup method签名总结前言看
- 本文实例讲述了java设计模式之工厂模式。分享给大家供大家参考,具体如下:工厂模式(factory)涉及到4个角色:抽象工厂类角色,具体工厂
- 本文实例讲述了Java Web项目部署在Tomcat运行出错与解决方法。分享给大家供大家参考,具体如下:1、在部署Java Web项目的过程
- 表示键/值对的集合,这些键和值按键排序并可按照键和索引访问。SortedList最合适对一列健/值对 进行排序,在排序时,是对键进行排序,S
- 每当想找哪个运算符优先级高时,很多时候总是想找的就没有,真让人气愤!现在,终于有个我个人觉得非常全的,分享给大家,欢迎拍砖!C语言运算符优先
- 在上篇文章给大家介绍了WebService教程详解(一)使用工具的原因:1、 使用工具可以更好的了解WebService请求的过程 2、 使
- 所以对于应用层用着还不是很方便。最近做一个项目顺便就封装了一个调用默认打印机的类。虽说有几个小bug,但对于目前来说,已经满足需求了。以后不
- 本文为大家分享了JSplitPane的使用方法,供大家参考,具体内容如下1、swing分割窗口控件JSplitPane,用来将窗口分割成两个
- The error simply says, “you've made changes in files in your works
- 主线程和子线程的区别每个线程都有一个唯一标示符,来区分线程中的主次关系的说法。 线程唯一标示符:Thread.CurrentThread.M
- 本章是后续学习的基石,只有充分理解了分布式系统的概念和面临的问题,以及ZooKeeper内部的概念,才能懂得ZooKeeper是如何对分布式