/** * 直播页面点赞特效,采用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实现)相关推荐

  1. android 水滴动画效果图,Android控件实现水滴效果

    看到ios版上QQ刷新效果像水滴,然后自己也想着去实现这样的效果,这篇文章暂时没有介绍下拉刷新的效果,只是单独用一个控件来实现这样的水滴效果. 效果图如下: 一.总体思路 1.画两个圆形,其中一个就是 ...

  2. android 360动画效果图,Android实现360手机助手底部的动画菜单

    首先来看下我们实现的效果和360效果的对比: 360手机助手效果演示 本库实现的效果(Icon来自360手机助手,侵删) xml布局文件 注:为了美观,讲每个Button的高度以及固定,设置wrap_ ...

  3. android 烟花动画效果图,Android 自定义 View 新年烟花、横幅动画

    新年了,项目中要作个动画,如下效果图: 整体要求实现:彩带乱飞,烟花冲天而起,烟花缩放,小鸡换图,小鸡飘移,横幅裁剪.展开等动画效果, 全局大量使用了属性动画来实现. 我在实现过程中,横幅的裁剪计算, ...

  4. android studio 动画效果图,Android Studio如何动画移动视图?

    我有一个问题.我怎样才能动画一个移动视图?我想生成一个字母,并在移动时对其进行动画处理(旋转和缩放).如果我只是开始动画就可以按照我的想法工作,或者如果我只运行移动方法,它也可以起作用,但不起作用.下 ...

  5. android属性动画作用范围,Android开发之动画效果浅析(一)

    程序运行效果图: Android动画主要包含补间动画(Tween)View Animation.帧动画(Frame)Drawable Animation.以及属性动画Property Animatio ...

  6. android svg动画框架,Android实现炫酷SVG动画效果

    svg是目前十分流行的图像文件格式了,svg严格来说应该是一种开放标准的矢量图形语言,使用svg格式我们可以直接用代码来描绘图像,可以用任何文字处理工具打开svg图像,通过改变部分代码来使图像具有交互 ...

  7. Android翻转动画(卡片翻转效果)

    文章目录 前言 需求 一.先介绍三个插值器 二.实现步骤 1.效果图 2.布局 3.逻辑判断(是否隐藏) 4.翻转动画 5.bug出现 6.bug解决 三.源码 MainActivity.java a ...

  8. Android\OPhone动画分析之翻转效果

    看到很多人在问如何实现三维的翻转效果,所以今天在这里简单的给大家分析一下,其实在APIDemo中就有这样一个例子,那么我们就以其为例来学习Android中的翻转动画效果的实现,首先看一下运行效果如下图 ...

  9. android倒计时动画特效,Android仿活动时分秒倒计时效果

    本文实例为大家分享了Android时分秒倒计时效果的具体代码,供大家参考,具体内容如下 从mian.xml下手: xmlns:tools="http://schemas.android.co ...

最新文章

  1. python对excel进行筛选-PythonEXCEL读取-保存-矩阵合并-条件筛选
  2. phpcms开启、关闭在线编辑模板的方法
  3. windows mysql 开启日志功能_Windows下开启mysql日志功能
  4. 阿里云 nginx php mysql_阿里云 Ubuntu + Nginx + PHP + MySQL
  5. Spring中ApplicationContext和beanfactory区别
  6. PathRemoveFileSpec函数
  7. Effective Java(一)———— 代替构造器和Setter的构建器模式
  8. label mpchart 饼图_Android MPChart—饼图-Go语言中文社区
  9. C程序设计语言现代方法08:数组
  10. 大型网站架构系列:负载均衡详解(4)
  11. Zabbix_Server 迁移之 Agent 地址批量修改
  12. 注解mysql事物管理_Spring 使用注解方式进行事务管理
  13. 如何写好一篇技术博客
  14. 串口485接法图_RS-485 2线和4线的接法
  15. 从零开始搭建自己的个人博客网站
  16. 湖南软件计算机单招较好学校,长沙岳麓区计算机IT单招学校排行榜
  17. ctDNA早期肿瘤×××基因检测
  18. 用计算机连接路由器,怎样连接路由器和电脑_电脑怎么链接路由器-系统城
  19. Censored! POJ - 1625
  20. Solidity入门-开发众筹智能合约

热门文章

  1. javascript字典中添加数组_Javascript 数组与字典
  2. python replace函数_Python pandas.DataFrame.replace函数方法的使用
  3. Android12之OpenSL ES衔接android侧播放器(十六)
  4. 学习的总方法论、天赋是积累形成的。
  5. PS进阶篇——如何PS软件液化之向前变形工具(九)
  6. Unity3d 2020 无法连接Visual Studio(2017/2022)进行断点调试(附加到Unity3d)问题
  7. C#中String转int问题
  8. 计算机网络设计函授论文,经典函授计算机论文题目 函授计算机论文题目怎么取...
  9. 函授大专计算机专业论文题目,函授大专最后的毕业论文可以不写吗
  10. 关闭2345的热点资讯