Android碎裂的粒子效果

最近看到一段時(shí)間都沒怎么更新文章了衫哥,一直在學(xué)習(xí)iOS相關(guān)內(nèi)容茎刚。偶然間看到一個(gè)碎裂的粒子效果,覺得很有意思撤逢,就查了查膛锭,參考下網(wǎng)上的思路自己擼了個(gè)輪子。

好了笛质,說了這么多泉沾,先看看效果吧~

粒子破碎效果

依慣例捞蚂,先說下行文思路吧妇押,首先我們先簡(jiǎn)單分析下效果,拆分關(guān)注點(diǎn)姓迅,粒子效果是怎么產(chǎn)生的敲霍?我的解決方案就是先獲取當(dāng)前要碎裂的view的緩存視圖,然后根據(jù)圖片獲取各個(gè)坐標(biāo)點(diǎn)的顏色值丁存,在整個(gè)DecorView蓋上一層視圖肩杈,這個(gè)視圖就根據(jù)獲取的顏色值在要碎裂的view的位置drawCircle,之后變化圓心和半徑以及透明度從而產(chǎn)生碎裂效果解寝。那么扩然,我們要解決的問題已經(jīng)簡(jiǎn)化為幾個(gè)點(diǎn)了,看怎么一個(gè)一個(gè)將其擊破聋伦。

一夫偶、獲取view的視圖
二、獲取要碎裂的view的位置以及獲取各個(gè)位置的顏色值
三觉增、變化各個(gè)屬性值產(chǎn)生動(dòng)畫碎裂效果

一兵拢、獲取view的視圖

獲取view的視圖也就是要獲取這個(gè)視圖的截圖,有兩種方式可以來做:

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;
    }

通過這兩種方式都可以獲取這個(gè)視圖的圖片,而為什么我們要獲取這個(gè)視圖的圖片呢,因?yàn)橐鶕?jù)這個(gè)圖片來獲取各個(gè)位置的顏色值腻扇,為之后繪制粒子效果服務(wù)债热。

二、獲取要碎裂的view的位置以及獲取各個(gè)位置的顏色值

獲取view的位置幼苛,之前使用過getGlobalVisibleRect方法來獲取位置阳柔,但很多時(shí)候并不是很準(zhǔn)確,比如有ActionBar的時(shí)候蚓峦。

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

之后測(cè)試使用getLocationInWindow這種方式挺不錯(cuò)舌剂,這個(gè)方法的官方注釋為這樣寫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());

在獲取視圖位置之后,我們要獲取各個(gè)位置的顏色值來繪制在這片區(qū)域內(nèi)暑椰,調(diào)用bitmap.getPixel方法獲取各個(gè)位置的顏色值:

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 ++) { //列
                //取得當(dāng)前粒子所在位置的顏色
                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;
    }

三、變化各個(gè)屬性值產(chǎn)生動(dòng)畫碎裂效果

首先我們要在當(dāng)前視圖上覆蓋一層產(chǎn)生碎裂效果的視圖:

 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);
    }

將我們要繪制粒子動(dòng)畫效果的添加進(jìn)布局視圖中一汽,然后我們就可以開始繪制了避消。
開啟屬性動(dòng)畫,根據(jù)動(dòng)畫流程變化Particle的相關(guān)屬性:

    //x值
    public float cx;
    //y值
    public float cy;
    //繪制圓的半徑
    public float radius;
    //顏色
    public int color;
    //透明度
    public float alpha;

在自定義視圖的onDraw方法召夹,遍歷所有我們保存的粒子Particle,改變相關(guān)屬性值:

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

    public void drawParticle(Canvas canvas) {
        //動(dòng)畫結(jié)束停止
        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();
    }
      //更新相關(guān)屬性值  主要是隨機(jī)生成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岩喷,到這里我們就基本實(shí)現(xiàn)了這個(gè)碎裂效果,整體注意點(diǎn)基本就這么多监憎,我把它簡(jiǎn)單封裝了下纱意,使用方式也很簡(jiǎn)單:

  final ParticleView particleAnimator = new ParticleView(MainActivity.this,3000);//3000為動(dòng)畫持續(xù)時(shí)間 
        particleAnimator.setOnAnimationListener(new ParticleView.OnAnimationListener() {
            @Override
            public void onAnimationStart(View view,Animator animation) {
                //動(dòng)畫開始
                view.setVisibility(View.INVISIBLE);
            }
            @Override
            public void onAnimationEnd(View view,Animator animation) {
                //動(dòng)畫結(jié)束
            }
        });
        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                particleAnimator.boom(v);//開始動(dòng)畫
            }
        });

github地址:ParticleDismissLayout

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鲸阔,隨后出現(xiàn)的幾起案子偷霉,更是在濱河造成了極大的恐慌,老刑警劉巖褐筛,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件类少,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡渔扎,警方通過查閱死者的電腦和手機(jī)硫狞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晃痴,“玉大人残吩,你說我怎么就攤上這事±⒌” “怎么了世剖?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)笤虫。 經(jīng)常有香客問我旁瘫,道長(zhǎng)祖凫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任酬凳,我火速辦了婚禮惠况,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宁仔。我一直安慰自己稠屠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布翎苫。 她就那樣靜靜地躺著权埠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪煎谍。 梳的紋絲不亂的頭發(fā)上攘蔽,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音呐粘,去河邊找鬼满俗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛作岖,可吹牛的內(nèi)容都是我干的唆垃。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼痘儡,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼辕万!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谤辜,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤蓄坏,失蹤者是張志新(化名)和其女友劉穎价捧,沒想到半個(gè)月后丑念,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡结蟋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年脯倚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嵌屎。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡推正,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宝惰,到底是詐尸還是另有隱情植榕,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布尼夺,位于F島的核電站尊残,受9級(jí)特大地震影響炒瘸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寝衫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一顷扩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慰毅,春花似錦隘截、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至着饥,卻和暖如春雕擂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贱勃。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工井赌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贵扰。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓仇穗,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親戚绕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子纹坐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,732評(píng)論 25 707
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜舞丛,今天將帶大家一窺ios動(dòng)畫全貌耘子。在這里你可以看...
    每天刷兩次牙閱讀 8,469評(píng)論 6 30
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件球切、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,058評(píng)論 4 62
  • 誰執(zhí)著 誰想寞落 記憶忘過 什么痛 什么你說 我曾記得 話說你 話說清風(fēng) 話說雨輕劃過 審視著 瞳孔緊縮 會(huì)有光火...
    小秀子乖乖閱讀 211評(píng)論 0 2
  • 青臺(tái)柳吨凑,青臺(tái)柳捍歪,細(xì)鎖山風(fēng)黛眉 影影綽綽,煢煢孑立 執(zhí)一念鸵钝,兩蒼茫糙臼,三世輪回 只愿攀折君之手
    高山子閱讀 221評(píng)論 0 2