最近看到一段时间都没怎么更新文章了,一直在学习iOS相关内容。偶然间看到一个碎裂的粒子效果,觉得很有意思,就查了查,参考下网上的思路自己撸了个轮子。

好了,说了这么多,先看看效果吧~

依惯例,先说下行文思路吧,首先我们先简单分析下效果,拆分关注点,粒子效果是怎么产生的?我的解决方案就是先获取当前要碎裂的view的缓存视图,然后根据图片获取各个坐标点的颜色值,在整个DecorView盖上一层视图,这个视图就根据获取的颜色值在要碎裂的view的位置drawCircle,之后变化圆心和半径以及透明度从而产生碎裂效果。那么,我们要解决的问题已经简化为几个点了,看怎么一个一个将其击破。

一、获取view的视图

二、获取要碎裂的view的位置以及获取各个位置的颜色值

三、变化各个属性值产生动画碎裂效果

一、获取view的视图

获取view的视图也就是要获取这个视图的截图,有两种方式可以来做:

1、可以用Canvas来获取Bitmap

public Bitmap getBitmapFromView(View view) {
    Bitmap bmp = Bitmap.createBitmap(webView.getWidth(),
    webView.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bmp);
    view.draw(canvas);
    return bmp;
}

2、用getDrawingCache来获取Bitmap

    private static Bitmap getCacheBitmapFromView(View view) {
        final boolean drawingCacheEnabled = true;
        view.setDrawingCacheEnabled(drawingCacheEnabled);
        view.buildDrawingCache(drawingCacheEnabled);
        final Bitmap drawingCache = view.getDrawingCache();
        Bitmap bitmap;
        if (drawingCache != null) {
            bitmap = Bitmap.createBitmap(drawingCache);
            view.setDrawingCacheEnabled(false);
        } else {
            bitmap = null;
        }
        return bitmap;
    }

通过这两种方式都可以获取这个视图的图片,而为什么我们要获取这个视图的图片呢,因为要根据这个图片来获取各个位置的颜色值,为之后绘制粒子效果服务。

二、获取要碎裂的view的位置以及获取各个位置的颜色值

获取view的位置,之前使用过getGlobalVisibleRect方法来获取位置,但很多时候并不是很准确,比如有ActionBar的时候。

Rect rect = new Rect();
view.getGlobalVisibleRect(rect);

之后测试使用getLocationInWindow这种方式挺不错,这个方法的官方注释为这样写Computes the coordinates of this view in its window.

 int[] location = new int[2];
 view.getLocationInWindow(location);
 Rect rect = new Rect(location[0],location[1],location[0]+view.getMeasuredWidth(),location[1]+view.getMeasuredHeight());

在获取视图位置之后,我们要获取各个位置的颜色值来绘制在这片区域内,调用bitmap.getPixel方法获取各个位置的颜色值:

public static Particle[][] generateParticles(Bitmap bitmap, Rect bound) {
        int w = bound.width();
        int h = bound.height();

        int partW_Count = w / Particle.PART_WH;
        int partH_Count = h / Particle.PART_WH;

        Particle[][] particles = new Particle[partH_Count][partW_Count];
        Point point = null;
        for (int row = 0; row < partH_Count; row ++) { //行
            for (int column = 0; column < partW_Count; column ++) { //列
                //取得当前粒子所在位置的颜色
                int color = bitmap.getPixel(column * Particle.PART_WH, row * Particle.PART_WH);
                point = new Point(column, row); //x是列,y是行
                particles[row][column] = Particle.generateParticle(color, bound, point);
            }
        }
        return particles;
    }

三、变化各个属性值产生动画碎裂效果

首先我们要在当前视图上覆盖一层产生碎裂效果的视图:

 private void attachToActivity(Activity activity) {
        ViewGroup rootView = (ViewGroup) activity.getWindow().getDecorView();
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        rootView.addView(this, lp);
    }

将我们要绘制粒子动画效果的添加进布局视图中,然后我们就可以开始绘制了。

开启属性动画,根据动画流程变化Particle的相关属性:

    //x值
    public float cx;
    //y值
    public float cy;
    //绘制圆的半径
    public float radius;
    //颜色
    public int color;
    //透明度
    public float alpha;

在自定义视图的onDraw方法,遍历所有我们保存的粒子Particle,改变相关属性值:

@Override
    protected void onDraw(Canvas canvas) {
        if (mParticleAnimator !=null)
            drawParticle(canvas);
    }

    public void drawParticle(Canvas canvas) {
        //动画结束停止
        if(!mParticleAnimator.isRunning()) {
            return;
        }
        for (Particle[] particle : mParticleAnimator.getParticles()) {
            for (Particle p : particle) {
                p.update((Float) mParticleAnimator.getAnimatedValue());
                mPaint.setColor(p.color);
                mPaint.setAlpha((int) (Color.alpha(p.color) * p.alpha));
                canvas.drawCircle(p.cx, p.cy, p.radius, mPaint);//
            }
        }
        invalidate();
    }
      //更新相关属性值  主要是随机生成x y值以及碎裂大小
      public void update(float factor) {
        cx = cx + factor * random.nextInt(mBound.width()) * (random.nextFloat() - 0.5f);
        cy = cy + factor * (mBound.height()/(random.nextInt(4)+1)) ;
        radius = radius - factor * random.nextInt(3);;
        if (radius<=0)
            radius = 0;
        alpha = 1f - factor;
    }

OK,到这里我们就基本实现了这个碎裂效果,整体注意点基本就这么多,我把它简单封装了下,使用方式也很简单:

  final ParticleView particleAnimator = new ParticleView(MainActivity.this,3000);//3000为动画持续时间
        particleAnimator.setOnAnimationListener(new ParticleView.OnAnimationListener() {
            @Override
            public void onAnimationStart(View view,Animator animation) {
                //动画开始
                view.setVisibility(View.INVISIBLE);
            }
            @Override
            public void onAnimationEnd(View view,Animator animation) {
                //动画结束
            }
        });
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                particleAnimator.boom(v);//开始动画
            }
        });

github地址:ParticleDismissLayout

Android碎裂的粒子效果的更多相关文章

  1. 两行代码搞定Android视图扩散切换效果

    用最简单的方式来实现Android视图扩散切换效果. 一.概述 这两天时间动手撸了个视图扩散切换效果的控制器,API兼容至Android4.0,更方便我们在视图切换过程中有炫酷的过渡效果.本来是想实现 ...

  2. Android特效--粒子效果之雨

    1. 单个雨点的行为 2. 完善雨点的行为和构造下雨场景 3. 在XML中定义可以控制下雨的属性 --------------------------------------------------- ...

  3. three.js粒子效果(分别基于CPU&GPU实现)

    前段时间做了一个基于CPU和GPU对比的粒子效果丢在学习WebGL的群里,技术上没有多作讲解,有同学反馈看不太懂GPU版本,干脆开一篇文章,重点讲解基于GPU开发的版本. 一.概况 废话不多说,先丢上 ...

  4. 超炫的HTML5粒子效果进度条 VS 如何规范而优雅地code

    最近瞎逛的时候发现了一个超炫的粒子进度效果,有多炫呢?请擦亮眼镜!   // _this.ch){ _this.particles.splice(i, 1); } }; this.Particle.p ...

  5. 解决Android Graphical Layout 界面效果不显示

    解决Android Graphical Layout 界面效果不显示 qq463431476

  6. android 的闪屏效果

    android的闪屏效果,就是我们刚开始启动应用的时候弹出的界面或者动画,过2秒之后自动的跳转到主界面. 其实,实现这个效果很简单,使用Handler对象的postDelayed方法就可以实现.在这个 ...

  7. 简直要逆天!超炫的 HTML5 粒子效果进度条

    我喜欢粒子效果作品,特别是那些能够应用于实际的,例如这个由 Jack Rugile 基于 HTML5 Cavnas 编写的进度条效果.看着这么炫的 Loading 效果,即使让我多等一会也无妨:)你呢 ...

  8. CodePen 作品秀:Canvas 粒子效果文本动画

    作品名称——Shape Shifter,基于 Canvas 的粒子图形变换实验.在页面下方的输入框输入文本,上面就会进行变换出对应的粒子效果文本动画. CodePen 作品秀系列向大家展示来自 Cod ...

  9. 兼容Android的水波纹效果

    Android的水波纹效果只有高版本才有,我们希望自己的应用在低版本用低版本的阴影,高版本用水波纹,这怎么做呢?其实,只要分drawable和drawablev21两个文件夹就好了. 普通情况下的se ...

随机推荐

  1. [Kaggle] dogs-vs-cats之制作数据集[1]

    Step 0:导入必要的库 import tensorflow as tfimport os Step 1:获取图片文件名以及对应的标签 首先是读取给定路径下所有图片的名称以及对应的标签.os.lis ...

  2. scrapy爬取豆瓣电影top250

    # -*- coding: utf-8 -*- # scrapy爬取豆瓣电影top250 import scrapy from douban.items import DoubanItem class ...

  3. 类相关的BIF

    1.>>> issubclass(C,A)#判断c是A的子类,返回真假 2.>>> isinstance(b1,B) #判断c1是B类的实例化对象,返回真假 3.& ...

  4. hdu3342-判断有向图中是否存在(至少)3元环或回路-拓扑排序

    一:题目大意:   给你一个关系图,判断是否合法,    每个人都有师父和徒弟,可以有很多个:  不合法:  1) . 互为师徒:(有回路)  2) .你的师父是你徒弟的徒弟,或者说你的徒弟是你师父的 ...

  5. angular中使用echart遇到的获取容器高度异常的问题记录

    问题 在使用echart去创建图表时,发现图表只占了容器的一个角落,如图,并没有充满容器. 第一反应是容器元素的样式有问题,于是我把容器的宽高都改为px指定的(之前是百分比设定的,查询资料发现说ech ...

  6. Oracle SQL Developer 免费的DB2客户端

    问题地址:https://stackoverflow.com/questions/8600735/is-there-any-opensource-db2-client 软件地址:http://www. ...

  7. selenium 设置代理的话,可以使用这种方式,代码是我刚才测试过的,亲测可用

    from selenium import webdriver chrome_options = webdriver.ChromeOptions() chrome_options.add_argumen ...

  8. [HAOI 2006]旅行comf

    Description 题库链接 给你一个 \(n\) 个点, \(m\) 条边的无向图.并给出一个点对 \((s,t)\) ,求 \(s,t\) 间的一条路径,使得路径上最大边和最小边的比值最小. ...

  9. [AHOI2006]基因匹配

    题目描述 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球上只有4种),而更奇怪的是,组成DNA序列的每一种碱基在该序列中正好出现5次!这样如果一个 ...

  10. [POI2009]KAM-Pebbles

    题目描述 Johny and Margaret are playing "pebbles". Initially there is a certain number of pebb ...