先上图:

这是一个高级UI特效,是个动画。

完成这个动画只要3步:

1、控件完成振动效果动画。
2、控件振动动画完成后消失,然后将控件转换成Bitmap.
3、Bitmap完成粒子爆炸特效。

其实完成粒子爆炸特效的并不是控件View本身,而是Bitmap,将Bitmap分割成多个小球,小球在x轴上随机地左右晃动,在y轴上径直下落就行了。

代码介绍:

Particle:

 public abstract class Particle {float x;float y;int color;public Particle(float x, float y, int color) {this.x = x;this.y = y;this.color = color;}//计算protected abstract void compute(float factor);//绘制protected abstract void draw(Canvas canvas,Paint paint);//逐步绘制protected void draw(Canvas canvas,Paint paint,float factor){compute(factor);draw(canvas,paint);}
}

这是一个粒子的抽象类,用于定义粒子的x,y坐标,颜色,计算x,y坐标的方法,绘制方法以及一个将这2个方法封装起来的新方法.

FallingParticle

public class FallingParticle extends Particle {private static final String TAG = "FallingParticle";private float radius = FallingParticleFactory.PART_WH;   //粒子半径private float alpha = 1.0f;  //透明度private Rect mBound;public FallingParticle(float x, float y, int color,Rect bound) {super(x, y, color);mBound = bound;}@Overrideprotected void compute(float factor) {x = x + factor * Utils.RANDOM.nextInt(mBound.width()) * (Utils.RANDOM.nextFloat() - 0.5f); y = y + factor * Utils.RANDOM.nextInt(mBound.height() / 2); radius = radius - factor * Utils.RANDOM.nextInt(2);  alpha = (1 - factor) * (1 + Utils.RANDOM.nextFloat());  }@Overrideprotected void draw(Canvas canvas, Paint paint) {paint.setColor(color);paint.setAlpha((int) (Color.alpha(color) * alpha));canvas.drawCircle(x,y,radius,paint);}
}

继承抽象方法Particle,主要具体计算粒子的x、y坐标,半径,透明度,具体算法如下:

x = x +(0-1↑) × [-0.5width,0.5width] ():表示从从0到1逐步上升的数,[]:表示这个区间内的任意一个随机数(下同)

y = y + (0-1↑) × [0,0.5h]

radius = radius - (0-1↑) × [0,2]

alpha = [0-1↓] × (1 + [0,1])

粒子工厂抽象方法

public abstract class ParticleFactory {protected abstract Particle[][] generateParticles(Bitmap bitmap, Rect bound);
}

用于生成粒子矩阵,只有一个方法用来生成所有粒子

粒子工厂

public class FallingParticleFactory extends ParticleFactory {private static final String TAG = "FallingParticleFactory";public static final int PART_WH = 8;  //粒子默认宽高@Overrideprotected Particle[][] generateParticles(Bitmap bitmap, Rect bound) {int w = bound.width();int h = bound.height();Log.d(TAG, "generateParticles: " + bound.left + "," + bound.top);int partW_count = w / PART_WH;  //横向个数int partH_count = h / PART_WH;  //竖向个数//判断个数是否小于1,这种情况是控件的大小 < 8partW_count = partW_count > 1 ? partW_count : 1;partH_count = partH_count > 1 ? partH_count : 1;int bitmap_part_w = bitmap.getWidth() / partW_count;int bitmap_part_h = bitmap.getHeight() / partH_count;Particle[][] particles = new Particle[partH_count][partW_count];for (int row = 0; row < partH_count; row++) {for (int column = 0; column < partW_count; column++) {//取得当前粒子所在位置颜色int color = bitmap.getPixel(column * bitmap_part_w,row * bitmap_part_h);float x = bound.left + column * PART_WH;float y = bound.top + row * PART_WH;particles[row][column] = new FallingParticle(x,y,color,bound);}}return particles;}
}

将一张Bitmap分割成多个粒子,每个粒子的宽、高为8(这个可以自己设定),Rect是包裹这个View的外围矩形,通过它的宽、高除以粒子的宽高后就可以得到每行有多少粒子,一共有多少行。

ExplosionField

public class ExplosionField extends View {private static final String TAG = "ExplosionField";private List<ExplosionAnimator> explosionAnimators;private OnClickListener onClickListener;public ExplosionField(Context context) {super(context);explosionAnimators = new ArrayList<>();//将动画区域添加到界面上attachToActivity();}private void attachToActivity() {//content是一个帧布局ViewGroup rootView = ((Activity) getContext()).getWindow().getDecorView().findViewById(android.R.id.content);ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);rootView.addView(this,params);}/*** 添加需要有粒子特效的View* @param view*/public void addListener(View view){if(view instanceof ViewGroup){ViewGroup viewGroup = (ViewGroup) view;int viewCount = viewGroup.getChildCount();for (int i = 0; i < viewCount; i++) {addListener(viewGroup.getChildAt(i));}}else{view.setOnClickListener(getOnClickListener());}}public OnClickListener getOnClickListener(){if(onClickListener == null){onClickListener = new OnClickListener() {@Overridepublic void onClick(View v) {explode(v);}};}return onClickListener;}//执行爆炸特效public void explode(final View view){final Rect rect = new Rect();view.getGlobalVisibleRect(rect); //获取View相对整个屏幕的位置//标题栏高度int titleHeight = ((ViewGroup) getParent()).getTop();//状态栏高度Rect frame = new Rect();((Activity) getContext()).getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);int statusBarHeight = frame.top;//相对整个屏幕的位置-标题栏(actionBar)的高度-状态栏的高度rect.offset(0,-titleHeight-statusBarHeight);if(rect.width() == 0 || rect.height() == 0){return;}//震动动画ValueAnimator animator = ValueAnimator.ofFloat(0f,1f).setDuration(150);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {view.setTranslationX((Utils.RANDOM.nextFloat() - 0.5f) * view.getWidth() * 0.05f);view.setTranslationY((Utils.RANDOM.nextFloat() - 0.5f) * view.getHeight() * 0.05f);}});animator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);explode(view,rect);}});animator.start();}private void explode(final View view,Rect bound){final  ExplosionAnimator explosionAnimator = new ExplosionAnimator(this,Utils.createBitmapFromView(view),bound);explosionAnimators.add(explosionAnimator);explosionAnimator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationStart(Animator animation) {view.setClickable(false);//缩小透明view.animate().setDuration(150).scaleX(0f).scaleY(0f).alpha(0f).start();}@Overridepublic void onAnimationEnd(Animator animation) {view.setClickable(true);//放大view.animate().setDuration(150).scaleX(1f).scaleY(1f).alpha(1f).start();explosionAnimators.remove(explosionAnimator);}});explosionAnimator.start();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);for (ExplosionAnimator explosionAnimator : explosionAnimators) {explosionAnimator.draw(canvas);}}
}

动画执行区域(其实是个View),首先将添加动画的控件设置点击监听器,如果这个控件是个ViewGroup,那么将它所有的子View设置点击监听器。紧接着执行振动动画,结束后执行粒子爆炸特效。

ExplosionAnimator

public class ExplosionAnimator extends ValueAnimator {private static final String TAG = "ExplosionAnimator";public static final int DEFAULT_DURATION = 1500;  //动画默认持续时间private Particle[][] mParticles;    //粒子们private ParticleFactory mParticleFactory;   //粒子工厂private View mContainer;   //动画执行区域private Paint mPaint;public ExplosionAnimator(View view, Bitmap bitmap, Rect bound) {mParticleFactory = new FallingParticleFactory();mPaint = new Paint();setFloatValues(0f,1f);setDuration(DEFAULT_DURATION);mParticles = mParticleFactory.generateParticles(bitmap,bound);mContainer = view;}public void draw(Canvas canvas){if(!isStarted()){//动画结束return;}//所有粒子开始运动for (Particle[] mParticle : mParticles) {for (Particle particle : mParticle) {particle.draw(canvas,mPaint,(float) getAnimatedValue());}}mContainer.invalidate();}@Overridepublic void start() {super.start();mContainer.invalidate();Log.d(TAG, "start: ");}
}

粒子爆炸动画实现类,继承于ValueAnimator,在draw方法中,遍历所以粒子并调用他们的draw方法,完成下一帧的绘制,值得注意的是,下方的invalidate方法会强制ExplosionField重绘,如图:

首先在ExplosionField中调用ExplosionAnimator的start方法,start方法中会使用invalidate方法来使ExplosionField重绘(调用onDraw方法),onDraw方法调用draw方法,draw方法中也使用invalidate,每一次循环完成一次重绘,整个动画就慢慢完成了。

demo地址:https://github.com/lyx19970504/Particle_Effect

android 粒子爆炸特效相关推荐

  1. Android粒子爆炸特效[可用于任意控件]

    小米手机用户可以看到,小米手机在应用卸载时会有一个粒子爆炸的特效效果,对此类动画效果垂涎已久,奈何一直没有机会用.正好最近项目里需要用到粒子爆炸的特效,于是便抽时间自己也试着仿写了一个效果出来. 先看 ...

  2. Android UI - 粒子爆炸特效

    Android UI - 粒子爆炸特效 效果 实现 分析 关键代码 源码 效果 实现 分析 首先动画效果需要在一个位于顶层的view上绘制,目的是不被其他控件遮挡. 添加点击事件,触发后给控件加一个抖 ...

  3. Android制作粒子爆炸特效

    简介 最近在闲逛的时候,发现了一款粒子爆炸特效的控件,觉得比较有意思,效果也不错. 但是代码不好扩展,也就是说如果要提供不同的爆炸效果,需要修改的地方比较多.于是我对源代码进行了一些重构,将爆炸流程和 ...

  4. Android 粒子爆炸效果,可以给任意 view 添加该效果

    ViewExplosion 项目地址:835127729/ViewExplosion 简介:Android 粒子爆炸效果,可以给任意 view 添加该效果 更多:作者   提 Bug   官网    ...

  5. MOGRT 金色粒子爆炸特效logo展示pr片头模板mogrt

    这是一个PR动态图形模板Mogrt,金色粒子爆炸特效logo展示PR片头模板mogrt.具有粒子效果的组合,这些效果结合在一起以显示和增强您的媒体. 此模板包含 1 个logo占位符和 1 个可编辑文 ...

  6. three.js 实现图片粒子爆炸特效

    大家好,这里是 CSS 魔法使--alphardex. 以下是最终实现的效果图 撒,哈吉马路由! 准备工作 笔者的three.js模板:点击右下角的fork即可复制一份 世界同步 在我的上一篇博文中, ...

  7. 使用opengl实现爆炸特效

    原理是用点阵展示图片,将点阵传给glsl里面的噪音方法更改位置. 图像对象 储存顶点数据 这里我设置了顶点数据和图片的顶点数据传入,因为顶点和图片的点阵不一样分开储存. public class Po ...

  8. AE484 3D大气电影风格LOGO视频片头爆炸烟雾粒子碎片特效动画制作ae模板

    AE484 3D大气电影风格LOGO视频片头爆炸烟雾粒子碎片特效动画制作ae模板 模板用途:3D,动作,电影,云,史诗,爆炸,火灾,灯光,标志揭示,金属,神秘,粒子,反射,烟雾 软件版本:后效CS6~ ...

  9. Android游戏开发–粒子爆炸

    有没有想过爆炸是如何产生的? 让我们绕个弯路,尝试实现基本的粒子爆炸. 爆炸不过是一堆散布在屏幕上的,源自单个点的粒子(无论是像素,小形状还是图像). 为了方便起见,并非总是如此,而是为了简洁起见,我 ...

最新文章

  1. h.265编码库x265实例
  2. db2 参数标识符使用无效_在Python应用程序中使用配置的最佳实践
  3. boost::mp11::mp_set_contains相关用法的测试程序
  4. @bean注解和@component注解的区别_通过源码查看 @Component,@Service 等注解是如何被解析的...
  5. html 文件上传与移除,Vue采用input实现文件上传与删除
  6. Oracle HTTP 乱码
  7. ARC075 F.Mirrored
  8. VS2013密钥(所有版本)
  9. segue跳转_使用SwiftUI的Segue Shenanigans
  10. python pip安装镜像源
  11. 消防联动控制系统服务器,火灾自动报警消防联动控制系统报价单V4.4.xls
  12. 基于MATLAB与Python计算长时间遥感栅格图像的像元值变异系数(CV)
  13. bitblt和getpixel哪个更效率
  14. 1.1 芯片研究背景及意义
  15. eclipse建maven项目报: Could not resolve archetype org.apache.maven.archetypes:maven-archetype-webapp:1.0
  16. [FFmpeg]编译av1的dav1d解码库
  17. P4850 [IOI2009]葡萄干raisins 记忆化搜索
  18. python中的pygame弹球游戏代码_python pygame实现挡板弹球游戏
  19. 【三维目标分类 】PointNet详解(一)
  20. 2-1径向基神经网络(RBF)代码

热门文章

  1. C语言重载宏函数的小技巧
  2. 零基础学习OpenCL(1)-安装OpenCL
  3. VMware启动虚拟机一直处于黑屏
  4. 李航《统计学习方法》第二版第一章-泛化误差
  5. Python 爬虫 Selenium 基本使用
  6. Maya2014下载安装与激活
  7. FleaPHP 开发指南 - 5. 应用程序设置
  8. WAS以及weblogic日志说明
  9. toft 测试用例rat_TD-LTE终端测试规范——通信功能和性能分册(上).pdf
  10. java计算机毕业设计东理咨询交流论坛源码+数据库+系统+lw文档+部署