Implementation analysis of View burst effect in Android <it Blue Panther >

Source: Internet
Author: User
Tags explode




A few days ago on Weibo by a very good Android open source Components Brush screen-Explosionfield, the effect is very cool, a bit like MIUI uninstall the APP when the animation, first to feel.
650) this.width=650; "src=" Https://github.com/tyrantgit/ExplosionField/raw/master/explosionfield.gif "title=" "/ >

Explosionfield not only the effect of the wind, the code is also very good, so people can not help but to take a good read.

Create Explosionfield

ExplosionFieldInherit from View , onDraw draw an animated effect in the method, and it provides a attach2Window way to add the ExplosionField most child view to the root view on the Activity.

public static Explosionfield Attach2window (activity activity) {ViewGroup Rootview = (viewgroup) Activity.findviewbyid (    Window.id_android_content);    Explosionfield Explosionfield = new Explosionfield (activity); Rootview.addview (Explosionfield, New Viewgroup.layoutparams (ViewGroup.LayoutParams.MATCH_PARENT, Viewgroup.lay    Outparams.match_parent)); return Explosionfield;} 1234567

explosionFieldLayoutParamsproperties are set to MATCH_PARENT ,
In this way, a view exploding particle can be plotted in the area where the Activity is located.

Knowledge Point: You can use window.id_android_content to replace ANDROID. R.id.content

The effect of shaking before exploding

In the view's click event, after the call mExplosionField.explode(v) , the view vibrates first and then burst.

The vibration effect is relatively simple, set a [0, 1] interval valueanimator, and then AnimatorUpdateListener onAnimationUpdate randomly translate the x and Y coordinates in the, and finally the scale and alpha value dynamically reduced to 0.

int startdelay = 100; Valueanimator animator = Valueanimator.offloat (0f, 1f). Setduration, Animator.addupdatelistener (new    Valueanimator.animatorupdatelistener () {Random random = new random (); @Override public void Onanimationupdate (Valueanimator animation) {View.settranslationx ((random.nextfloat ()-0.        5f) * View.getwidth () * 0.05f);    View.settranslationy ((Random.nextfloat ()-0.5f) * view.getheight () * 0.05f); }}); Animator.start (); View.animate (). Setduration (Startdelay). Setstartdelay ScaleX (0f). ScaleY (0f). Alpha (0f) . Start (); 123456789101112131415
Create a bitmap based on View

When the View vibrates, it begins with the hardest burst, and the burst is carried out in parallel with the hidden one, first look at the exploding API- void explode(Bitmap bitmap, Rect bound, long startDelay, long duration) :

The first two parameters bitmap and bound are key, and it's interesting to create bitmap code with View.

If View is a ImageView, and its drawable is a bitmapdrawable you can get the Bitmap directly.

if (view instanceof ImageView) {drawable drawable = ((ImageView) view). Getdrawable (); if (drawable! = null && drawable instanceof bitmapdrawable) {return ((bitmapdrawable) drawable). Getbitmap (    ); }}123456

If it is not a ImageView, you can create a bitmap by following these steps:

    1. Create a new Canvas

    2. Creates an empty bitmap based on the size of the View

    3. Set the empty bitmap as the canvas's base cloth

    4. Draw the view on the canvas

    5. Set the canvas's bitmap to NULL

Of course, the focus of the view should be cleared before drawing, because the focus may change the UI state of a view.
The Scanvas used in the code is a static variable, which saves the overhead of each creation.

View.clearfocus (); Bitmap Bitmap = createbitmapsafely (View.getwidth (), View.getheight (), Bitmap.Config.ARGB_8888, 1); if (Bitmap! = nul        L) {synchronized (Scanvas) {Canvas canvas = Scanvas;        Canvas.setbitmap (bitmap);        View.draw (canvas);    Canvas.setbitmap (NULL); }}1234567891011

The author's approach to creating bitmaps is ingenious, and if you create an OOM when you create a new Bitmap, you can proactively do GC-and System.gc() then try to create it again.

The way this function is implemented makes people admire the author's skill.

public static bitmap createbitmapsafely (int width, int  Height, bitmap.config config, int retrycount)  {    try {         return bitmap.createbitmap (width, height,  Config);    } catch  (outofmemoryerror e)  {         e.printstacktrace ();        if  ( retrycount > 0)  {             System.GC ();            return  Createbitmapsafely (width, height, config, retrycount - 1);         }        return null;     }}123456789101112 

Out of the bitmap, there is also a very important parameter bound, it is relatively simple to create:

Rect r = new rect (); View.getglobalvisiblerect (R); int[] location = new Int[2];getlocationonscreen (location); R.offset (- Location[0],-location[1]); R.inset (-mexpandinset[0],-mexpandinset[1]); 123456

First get the global viewable area of the view that needs to burst--and Rect r then, by getting the getLocationOnScreen(location) ExplosionField coordinates in the screen and panning the visible area of the exploded view According to this coordinate, the burst effect appears in the ExplosionField , and then extend it according to the Mexpandinset value (default is 0).

What is the use of the bitmap and bound created? We continue to analyze.

Creating particles

Let's take a look at the whole picture of this method of exploding into particles:

public void explode (Bitmap bitmap, rect bound, long  startdelay, long duration)  {    final ExplosionAnimator  Explosion = new explosionanimator (This, bitmap, bound);     Explosion.addlistener (New animatorlisteneradapter ()  {          @Override         public void onanimationend (Animator  animation)  {             Mexplosions.remove (animation);         }    });     explosion.setstartdelay (Startdelay);     explosion.setduration ( Duration);     mexplosions.add (explosion);     explosion.start ();} 12345678910111213 

Here's an explanation of why a container class variable-- mExplosions to save one ExplosionAnimator . Because the explosion effect of multiple view in activity may have to be done at the same time, so the burst animation of each view corresponding to save, and so on when the end of the animation deleted.

The author customizes a class that inherits from Valueanimator-Explosionanimator, which mainly does two things, one is to create particles- generateParticle and the other is to draw particles- draw(Canvas canvas) .

Let's take a look at the constructor:

Public explosionanimator (View container, bitmap bitmap, rect bound)  {     mpaint = new paint ();     mbound = new rect (bound);     int partlen = 15;    mparticles =  new Particle[partLen * partLen];    Random random =  New random (System.currenttimemillis ());     int w = bitmap.getwidth ()  /  (PARTLEN&NBSP;+&NBSP;2);     int h = bitmap.getheight ()  /   (PARTLEN&NBSP;+&NBSP;2);    for  (int i = 0; i <  partlen; i++)  {        for  (int j =  0; j < partlen; j++)  {             mparticles[(I * partlen)  + j] = generateparticle (Bitmap.getpixel (j + 1)  *  w,  (i + 1)  * h),  random);         }     }    mContainer = container;     Setfloatvalues (0f, end_value);     setinterpolator (Default_interpolator);     setduration (default_duration);} 123456789101112131415161718

According to the constructor, it is known that the author divides the bitmap into a matrix of x 17, and the width and height of each element are respectively w h .

int w = bitmap.getwidth ()/(Partlen + 2), int h = bitmap.getheight ()/(Partlen + 2); 12

All particles are a matrix of x 15, and the meta-plain value is the pixel value of the bitmap.

Bitmap.getpixel ((j + 1) * W, (i + 1) * h) 1

The structure is shown, where the hollow part is the particle.

                                    &NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0  0 0 0     0 0 0 0 0 0 0 0 0 0  0 0 0 0 0     0 0 0 0 0 0 0 0  0 0 0 0 0 0 0     0 0 0 0 0 0  0 0 0 0 0 0 0 0 0     0 0 0 0  0 0 0 0 0 0 0 0 0 0 0     0 0  0 0 0 0 0 0 0 0 0 0 0 0 0     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0     0 0 0 0  0 0 0 0 0 0 0 0 0 0 0     0 0  0 0 0 0 0 0 0 0 0 0 0 0 0     0 0 0 0 0 0 0 0 0 0 0 0 0 0 0     &NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0&NBSP;0  0 0     0 0 0 0 0 0 0 0 0 0 0  0 0 0 0     0 0 0 0 0 0 0 0 0  0 0 0 0 0 0     0 0 0 0 0 0 0  0 0 0 0 0 0 0 0                            &NBSP;       

generateParticleA particle is randomly generated based on a certain algorithm. This part is more cumbersome, analysis omitted.

One of the more ingenious is its draw method:

Public boolean draw (Canvas canvas)  {    if  (!isstarted ())  {         return false;    }     for  (particle particle : mparticles)  {         particle.advance (float)  getanimatedvalue ());         if  (particle.alpha > 0f)  {             mpaint.setcolor (Particle.color);             mpaint.setalpha ((int)   (Color.alpha (Particle.color)  * particle.alpha));             canvas.drawcircle (particle.cx, particle.cy,  Particle.radius, mpaint);        }    }     mcoNtainer.invalidate ();     return true;} 123456789101112131415

At first I was still confused, since the drawing of particles is in ExplosionField the onDraw method, it must be constantly refreshed, the results of the author does not do so, the implementation of the method is truly amazing.

First, the author ExplosionAnimator overloads the method in the class start() and calls mContainer.invalidate(mBound) to refresh the chunk corresponding to the View that will explode.

@Overridepublic void Start () {Super.start (); Mcontainer.invalidate (Mbound);} 12345

And Mcontainer is the view that fills the activity--the ExplosionField method in which it is onDraw called ExplosionAnimator draw .

@Overrideprotected void OnDraw (canvas canvas) {super.ondraw (canvas);    for (Explosionanimator explosion:mexplosions) {explosion.draw (canvas); }}1234567

The

Then forms a recursive, which calls each other and refreshes continuously until the alpha value of all particles becomes 0, and the refresh stops.

Public boolean draw (Canvas canvas)  {    if  (!isstarted ())  {         return false;    }     for  (particle particle : mparticles)  {         particle.advance (float)  getanimatedvalue ());         if  (particle.alpha > 0f)  {             mpaint.setcolor (Particle.color);             mpaint.setalpha ((int)   (Color.alpha (Particle.color)  * particle.alpha));             canvas.drawcircle (particle.cx, particle.cy,  Particle.radius, mpaint);        }    }     mcoNtainer.invalidate ();     return true;} 123456789101112131415
Summarize

This open Source Library code quality is very high, very much admire the author.


More Effects ... "It Blue Panther"



Implementation analysis of View burst effect in Android <it Blue Panther >

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.