android 烟花动画效果图,Android烟花效果(SurfaceView实现)
/** * 直播页面点赞特效,采用SurfaceView绘制 * 与普通控件使用方法类似,点赞是只需要调用startBomb()即可 */
public class BombView extends SurfaceView implements SurfaceHolder.Callback {
private static final int MAX_BUBBLE_COUNT = 90;
private SurfaceHolder mHolder;
private DrawTask mDrawTask; // 绘制UI的线程
private Paint mPaint; // 绘制需要使用的画刷
private FuseView mFuseView; // 引导的view
private boolean mIsDismiss = false; //是否处于消失阶段
private int mWidth; // 控件的宽度
private int mHeight; // 控件的高度
private int mBombX; // 旋转的中心X
private int mBombY; // 旋转的中心Y
private int dx = 0; // 引导view在坐抛物线运动时在x轴的增量
private Bitmap[] mDrawables; // 存放需要展示的图
private int[] mDrawableResIDs; // 存放需要展示的图
private List mBubbles = Collections.synchronizedList(new LinkedList()); // 用于存放点赞信息
private Random mRandom = new Random(); // 用于产生随机数
public BombView(Context context, AttributeSet attrs) {
super(context, attrs);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setKeepScreenOn(true);
mHolder.setFormat(PixelFormat.TRANSPARENT);
mPaint = new Paint();
mDrawableResIDs = new int[] {
R.drawable.praise_eight,
R.drawable.praise_one,
R.drawable.praise_third,
R.drawable.praise_two,
R.drawable.praise_five,
R.drawable.praise_four,
R.drawable.praise_seven,
R.drawable.praise_six,
};
mDrawables = new Bitmap[mDrawableResIDs.length];
}
@Override
protected void onDraw(final Canvas canvas) {
if (canvas != null) {
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); // 清空界面
if (mFuseView == null) {
return;
}
if (mFuseView.y+mFuseView.bitmap.getHeight()/2 > mBombY) {
mPaint.setAlpha(255);
if (mFuseView.x+mFuseView.bitmap.getWidth()/2 > mWidth/2) { // 抛物线
mFuseView.scale = dx*1.5f/mWidth + 1f;
canvas.save();
mFuseView.x = mWidth*7/8 - dx;
mFuseView.y = (int) getY(dx);
canvas.scale(mFuseView.scale, mFuseView.scale, mFuseView.x+mFuseView.bitmap.getWidth()/2, mFuseView.y+mFuseView.bitmap.getHeight()/2);
canvas.drawBitmap(mFuseView.bitmap, mFuseView.x, mFuseView.y, mPaint);
canvas.restore();
dx += dip2px(4);
} else { // 直线上升
canvas.save();
canvas.scale(mFuseView.scale, mFuseView.scale, mFuseView.x+mFuseView.bitmap.getWidth()/2, mFuseView.y+mFuseView.bitmap.getHeight()/2);
canvas.drawBitmap(mFuseView.bitmap, mFuseView.x, mFuseView.y, mPaint);
canvas.restore();
mFuseView.y -= dip2px(5);
}
postDelayed(mDrawTask, 5);
} else {
if (!mIsDismiss) {
mIsDismiss = mBubbles.size() > 0 && mBubbles.get(0).top < mWidth*9/20;
}
for (int i=mBubbles.size()-1; i>=0; i--) { // 绘制气泡
drawBubble(canvas, mBubbles.get(i));
}
// 大爱心放大消失
mFuseView.x = mBombX - mFuseView.bitmap.getWidth()/2;
mFuseView.y = mBombY - mFuseView.bitmap.getHeight()/2;
mFuseView.scale += 0.2;
mFuseView.alpha = (int)((5-mFuseView.scale)*85);// ps:85 = 255/3 根据缩放倍数来计算透明度
if (mFuseView.alpha > 0) {
mPaint.setAlpha(mFuseView.alpha);
canvas.save();
canvas.scale(mFuseView.scale, mFuseView.scale, mBombX, mBombY);
canvas.drawBitmap(mFuseView.bitmap, mFuseView.x, mFuseView.y, mPaint);
canvas.restore();
}
if (mBubbles.size() > 0) {
postDelayed(mDrawTask, 10);
} else {
release();
}
}
}
}
private void drawBubble(Canvas canvas, Bubble bubble) {
if (bubble.top + bubble.bitmap.getHeight()/2 > mWidth/2) {
bubble.top = bubble.top - dip2px(2);
return;
}
if (mIsDismiss) {
bubble.alpha -= 12;
if (bubble.alpha < 0) {
mBubbles.remove(bubble);
return;
}
}
bubble.top -= dip2px(0.5f);
if (bubble.scale < 1.2f) {
bubble.scale += 0.015f;
}
mPaint.setAlpha(bubble.alpha);
canvas.save();
canvas.scale(bubble.scale, bubble.scale, bubble.left+bubble.bitmap.getWidth()/2, bubble.top+bubble.bitmap.getHeight()/2);
canvas.rotate(bubble.rotate, mBombX, mBombY);
canvas.drawBitmap(bubble.bitmap, bubble.left, bubble.top, mPaint);
canvas.restore();
}
/** * 开始绘制爆炸彩蛋,如果上一个效果还没结束,则不处理新的 */
public void startBomb() {
if (mFuseView != null) {
return;
}
initFuseView();
generateBubble(MAX_BUBBLE_COUNT);
dx = 0;
mIsDismiss = false;
post(mDrawTask);
}
/** * 初始化引导 */
private void initFuseView() {
mFuseView = new FuseView();
mFuseView.x = mWidth*7/8;
mFuseView.y = mHeight*17/20;
mFuseView.bitmap = BitmapUtil.readBitmap(getResources(), R.drawable.praise_five);
}
/** * 添加点赞,会对传入的个数进行处理 *@param count */
private void generateBubble(int count) {
for (int i = 0; i < count; i++) {
Bubble bubble = new Bubble();
bubble.bitmap = getRandBitmap();
bubble.alpha = 155 + mRandom.nextInt(100);
bubble.scale = 0.6f + mRandom.nextFloat()*0.4f;
// bubble.rotate = mRandom.nextInt(360);
bubble.rotate = 360*i/count; // 由于绘制时还需要缩放,不然可以使用增量旋转,即不用每次都restore
if (bubble.rotate > 180) { // 反向旋转
bubble.rotate = bubble.rotate - 360;
}
bubble.left = mWidth/2 - bubble.bitmap.getWidth()/2;
float offset = 0;
if (i % 2 == 0) {
offset = mWidth*0.1f + mWidth*0.15f * i/count;
}
if (i%3 == 0) {
offset = mWidth*0.25f + mWidth*0.15f * i/count;
}
if (i%5 == 0) {
offset = mWidth*0.4f + mWidth*0.12f * mRandom.nextFloat();
}
bubble.top = offset - bubble.bitmap.getHeight();
mBubbles.add(0, bubble);
}
mBubbles.get(0).top = mWidth*0.52f - dip2px(5); // 以第一个气泡的位置判断是否该dismiss
mBubbles.get(0).alpha = 1; // 防止正在消失时突然显现出来
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
this.mWidth = width;
this.mHeight = height;
mBombX = mWidth/2;
mBombY = mWidth/2;
}
class Bubble {
public Bitmap bitmap;
public float scale = 1.0f; // 缩放
public float top = 0f; // 偏移
public float left = 0f; // 偏移
public int rotate = 0; // 旋转
public int alpha = 255; // 透明度
public Bubble() {
this.bitmap = getRandBitmap();
}
}
class FuseView {
public Bitmap bitmap;
public float scale;
public int alpha;
public int x;
public int y;
}
// 抛物线
private float getY(float x) {
return mHeight*10/11 - 0.009f * x * x;
}
public void release() {
mFuseView = null; // 防止过度绘制
for (Bitmap bitmap : mDrawables) {
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
}
}
}
}
android 烟花动画效果图,Android烟花效果(SurfaceView实现)相关推荐
- android 水滴动画效果图,Android控件实现水滴效果
看到ios版上QQ刷新效果像水滴,然后自己也想着去实现这样的效果,这篇文章暂时没有介绍下拉刷新的效果,只是单独用一个控件来实现这样的水滴效果. 效果图如下: 一.总体思路 1.画两个圆形,其中一个就是 ...
- android 360动画效果图,Android实现360手机助手底部的动画菜单
首先来看下我们实现的效果和360效果的对比: 360手机助手效果演示 本库实现的效果(Icon来自360手机助手,侵删) xml布局文件 注:为了美观,讲每个Button的高度以及固定,设置wrap_ ...
- android 烟花动画效果图,Android 自定义 View 新年烟花、横幅动画
新年了,项目中要作个动画,如下效果图: 整体要求实现:彩带乱飞,烟花冲天而起,烟花缩放,小鸡换图,小鸡飘移,横幅裁剪.展开等动画效果, 全局大量使用了属性动画来实现. 我在实现过程中,横幅的裁剪计算, ...
- android studio 动画效果图,Android Studio如何动画移动视图?
我有一个问题.我怎样才能动画一个移动视图?我想生成一个字母,并在移动时对其进行动画处理(旋转和缩放).如果我只是开始动画就可以按照我的想法工作,或者如果我只运行移动方法,它也可以起作用,但不起作用.下 ...
- android属性动画作用范围,Android开发之动画效果浅析(一)
程序运行效果图: Android动画主要包含补间动画(Tween)View Animation.帧动画(Frame)Drawable Animation.以及属性动画Property Animatio ...
- android svg动画框架,Android实现炫酷SVG动画效果
svg是目前十分流行的图像文件格式了,svg严格来说应该是一种开放标准的矢量图形语言,使用svg格式我们可以直接用代码来描绘图像,可以用任何文字处理工具打开svg图像,通过改变部分代码来使图像具有交互 ...
- Android翻转动画(卡片翻转效果)
文章目录 前言 需求 一.先介绍三个插值器 二.实现步骤 1.效果图 2.布局 3.逻辑判断(是否隐藏) 4.翻转动画 5.bug出现 6.bug解决 三.源码 MainActivity.java a ...
- Android\OPhone动画分析之翻转效果
看到很多人在问如何实现三维的翻转效果,所以今天在这里简单的给大家分析一下,其实在APIDemo中就有这样一个例子,那么我们就以其为例来学习Android中的翻转动画效果的实现,首先看一下运行效果如下图 ...
- android倒计时动画特效,Android仿活动时分秒倒计时效果
本文实例为大家分享了Android时分秒倒计时效果的具体代码,供大家参考,具体内容如下 从mian.xml下手: xmlns:tools="http://schemas.android.co ...
最新文章
- python对excel进行筛选-PythonEXCEL读取-保存-矩阵合并-条件筛选
- phpcms开启、关闭在线编辑模板的方法
- windows mysql 开启日志功能_Windows下开启mysql日志功能
- 阿里云 nginx php mysql_阿里云 Ubuntu + Nginx + PHP + MySQL
- Spring中ApplicationContext和beanfactory区别
- PathRemoveFileSpec函数
- Effective Java(一)———— 代替构造器和Setter的构建器模式
- label mpchart 饼图_Android MPChart—饼图-Go语言中文社区
- C程序设计语言现代方法08:数组
- 大型网站架构系列:负载均衡详解(4)
- Zabbix_Server 迁移之 Agent 地址批量修改
- 注解mysql事物管理_Spring 使用注解方式进行事务管理
- 如何写好一篇技术博客
- 串口485接法图_RS-485 2线和4线的接法
- 从零开始搭建自己的个人博客网站
- 湖南软件计算机单招较好学校,长沙岳麓区计算机IT单招学校排行榜
- ctDNA早期肿瘤×××基因检测
- 用计算机连接路由器,怎样连接路由器和电脑_电脑怎么链接路由器-系统城
- Censored! POJ - 1625
- Solidity入门-开发众筹智能合约
热门文章
- javascript字典中添加数组_Javascript 数组与字典
- python replace函数_Python pandas.DataFrame.replace函数方法的使用
- Android12之OpenSL ES衔接android侧播放器(十六)
- 学习的总方法论、天赋是积累形成的。
- PS进阶篇——如何PS软件液化之向前变形工具(九)
- Unity3d 2020 无法连接Visual Studio(2017/2022)进行断点调试(附加到Unity3d)问题
- C#中String转int问题
- 计算机网络设计函授论文,经典函授计算机论文题目 函授计算机论文题目怎么取...
- 函授大专计算机专业论文题目,函授大专最后的毕业论文可以不写吗
- 关闭2345的热点资讯