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


猜你喜欢
- 序目前最新的版本是 C# 7.0,VS 的最新版本为 Visual Studio 2017 RC,两者都尚未进入正式阶段。C# 6.0 虽说
- 前言这里主要简单介绍如何使用Camera+SurfaceView自定义相机拍照,如果是Camera2或者是TextureView的可以前往主
- 目录一 首先我们的去知道什么是反射?二(刨根问底)知道是什么还需要知道什么“成分”组成反射?2.1 Class 对象的获取及使用2.2 拿到
- 作为Android的四大组件之一,ContentProvider作为进程之间静态数据传递的重要手段,其在系统级别的应用中起了重大的作用。毫无
- 这篇文章主要介绍了Springboot配置文件内容加密代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 将DataGrid中上面这个表头变成下面的两行表头,你会怎么实现?很巧妙地截断和补充td tr来实现来源:http://www.cnsend
- 前言从windows窗口的概念开始,通过对比去理解Android窗口体系,本文没有深入源码,重在理解概念代码都是抄来抄去,概念也是互相借鉴
- 本文实例讲述了Android编程实现VideoView循环播放功能的方法。分享给大家供大家参考,具体如下:package com.hangc
- 一. switch分支结构1. 简介switch结合case,能够判断一个变量或表达式与一系列值中的某个值是否相等,这里的每个值都被称为一个
- 1、CountDownLatch:一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。2、ThreadPoolE
- 前言 之前的文章有介绍ActivityGroup,不少人问嵌套使用的问题,同样的需求在Fragment中也存在,幸好在最新的An
- 前言:上篇C#进阶系列——WebApi接口传参不再困惑:传参详解介绍了WebApi参数的传递,这篇来看看WebApi里面异常的处理。关于异常
- 前言:项目是c#的winform 写的,使用的播放器是基于AxWindowsMediaPlayer。AxWindowsMediaPlayer
- C语言用结构体实现一个通讯录,通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址提供方法:1. 添加联系人
- java内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类 。在java的世界里,提供了匿名内部类语法,用于帮助大家简化代码,本文
- 本文实例为大家分享了Unity创建平铺网格地图的具体代码,供大家参考,具体内容如下创建预制件先拖进场景,再从层级拖回资源选中源图像文件,设置
- 本文将通过AOP的方式实现一个相对更加简易灵活的API安全认证服务。我们先看实现,然后介绍和分析AOP基本原理和常用术语。一、Authori
- SpringBoot整合Log4j2以及配置详解SpringBoot整合Log4j2步骤:1、删除spring-boot-starter-p
- 本文实例为大家分享了Android仿京东左侧分类条目效果的具体代码,供大家参考,具体内容如下import android.app.Activ
- 测试APP时出现以下错误信息:Intel HAXM is required to run this AVD.Your CPU does no