Android Image Bounce Animation

Source: Internet
Author: User

These days to see a small animation, feel a little meaning, on their own realization to see, first look at


OK, the basic function of this effect is, a picture, fell from the top, after a few rounds, then stop, to achieve or relatively simple, but also went a little detour, here recorded.


There is a time to do custom control more, a little poisoned, see any effect first think of the custom control, so at first I was using a custom control nested their own animation to calculate the distance to achieve, and later found not necessary, but the basic idea is consistent, here first see how the custom control nested animation implementation.


Start by customizing a viewgroup, and look at some of the variables used inside

private int mwidth; The screen width    is private int mheight;//The screen height    private Boolean Mfirst = true;//whether the private int mtotalround is executed for the first time    ;//Total number of times    private int mcurround;//Current number of    private long mTime;//Animation time
Have comments, the main attention to the next number of times, where the picture falls or bounces, is counted as an animation

After the end of the implementation of a method to add pictures

private void Init () {        ImageView view = new ImageView (mcontext);        View.setbackgroundresource (r.mipmap.jump);        View.setscaletype (ImageView.ScaleType.FIT_XY);        AddView (view);    }

This is nothing to say, is to define a ImageView, set the picture, full screen, after the end will ImageView join ViewGroup.

Next, implement the Onmeasure method to get the screen width high, which is useful in later animations

@Override    protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {        mwidth = measurespec.getsize (WIDTHMEASURESPEC);   Get viewgroup width        mheight = measurespec.getsize (heightmeasurespec);  Get viewgroup height        setmeasureddimension (mwidth, mheight);    Sets the ViewGroup width-height        if (mfirst) {            Mfirst = false;            BeginAnimation ();        }    }

Here Mfirst is a Boolean variable, initially true, here is the animation is executed only once, no matter how many times into the Onmeasure method, BeginAnimation is the animation we are going to make.

Before implementing the animation, let's take a closer look at the animation, this animation looks very simple, but there are a few details to note:

1. The height of the animation is getting smaller, I am here for the first time to bounce the height of the screen 1/2, the second bounce up 1/4, the third bounce 1/8, and so on

2. We consider the image of a drop or bounce as an animation, the animation time is getting shorter, assuming that the first fall animation needs 1 seconds, the first time to play up to 1/2 seconds, the second fall is 1/2 seconds, the second bounce will take 1/4 seconds, and so on

3. When falling, faster and faster, when bouncing, faster and slower

Knowing these details, I can use the layout method to dynamically change the position of the ImageView, so as to achieve the effect of animation, layout method is very simple

public void layout (int l, int t, int r, int b)
Pass in left, top, right, bottom value to absolute position, left and right we do not have to pay attention, because the picture is moved up and down, so left constant for 0, and right constant for the width of the screen, and top and bottom are real-time changes, Look at the change in the value of top and bottom in order, assuming the screen height is mheight

The first animation, the picture falling from the top of the screen to the bottom of the screen, top changes from-mheight to 0,bottom changes from 0 to Mheight
The second animation, the picture from the bottom of the screen up to the bottom of the picture is exactly 1/2 of the screen height, top changes from 0 to-mheight/2,bottom changes from Mheight to MHEIGHT/2

The third animation, the bottom of the picture from the screen height of 1/2 falling to the bottom of the screen, top changes from-MHEIGHT/2 to 0,bottom changes from MHEIGHT/2 to Mheight

And so on, the following animations are all similar, and these are all clear, and you can see directly how the animation is implemented

private void BeginAnimation () {final int height;        if (mcurround% 2 = = 0) {//down height = (int) (-mheight * MATH.POW (0.5, MCURROUND/2));        } else {//up height = (int) (-mheight * MATH.POW (0.5, (Mcurround + 1)/2)); } Animation translateanimation = new Animation () {@Override protected void Applytransformati On (float interpolatedtime, transformation t) {if (mcurround% 2 = = 0) {getchildat (0). l                Ayout (0, (int) (height * (1-interpolatedtime)), mwidth, mheight + height-(int) (Interpolatedtime * height)); } else {getchildat (0). Layout (0, (int) (height * interpolatedtime), mwidth, mheight + (int) (HEI                Ght * interpolatedtime));        }            }        };            if (mcurround% 2 = = 0) {translateanimation.setinterpolator (New Accelerateinterpolator ()); Translateanimation.setduration ((Long) (MTime * MATH.POW (0).5, MCURROUND/2)));            } else {translateanimation.setinterpolator (new Decelerateinterpolator ());        Translateanimation.setduration ((Long) (MTime * MATH.POW (0.5, (Mcurround + 1)/2));        } startanimation (Translateanimation); Translateanimation.setanimationlistener (New Animation.animationlistener () {@Override public void on Animationstart (Animation Animation) {} @Override public void Onanimationend (Animation an                Imation) {mcurround++;                if (Mcurround < Mtotalround) {beginanimation (); }} @Override public void Onanimationrepeat (Animation Animation) {}})    ; }
Mcurround is the current number of animations, starting from 0 to count, modulo 2 is 0, that is, even, that is, drop, modulo 2 is 1, that is, odd, that is, bouncing, the back of the Applytransformation method, there is a parameter interpolatedtime, During the execution of the animation, the Applytransformation method is constantly called, and the value of Interpolatedtime changes from 0 to 1, and we can dynamically calculate the current height based on this value, The calculation method refers to the top of each animation above and the value of the bottom range of changes, you can draw on the paper to know. Behind the
if (mcurround% 2 = = 0) {            translateanimation.setinterpolator (new Accelerateinterpolator ());            Translateanimation.setduration ((Long) (MTime * MATH.POW (0.5, MCURROUND/2)));        } else {            translateanimation.setinterpolator (new Decelerateinterpolator ());            Translateanimation.setduration ((Long) (MTime * MATH.POW (0.5, (Mcurround + 1)/2));        }
In the previous analysis, the animation drop and bounce rate change, animation time is also getting shorter.

Finally, at the end of the animation execution, judging how many of the current animation execution, if not finished to continue to perform the next animation, here is a recursive call. Code implementation is quite simple, the key is the previous analysis process, and the attention to detail, the following post complete code

public class Jumpactivity extends Activity {private int totalround = 10;    private int time = 2000;        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);    Setcontentview (New Bounceview (this, totalround, time)); }}
public class Bounceview extends ViewGroup {private Context mcontext; private int mwidth; Screen width private int mheight; Screen height Private Boolean mfirst = true; Whether to execute the private int mtotalround for the first time; Total number of private int mcurround; Current number of private long mTime;        Animation Time Public Bounceview (context context) {super (context);    Init ();        } public Bounceview (context context, AttributeSet Attrs) {Super (context, attrs);    Init ();        } public Bounceview (context context, int roundnum, long time) {super (context);        Mcontext = context;        MTime = time;        Mtotalround = Roundnum;    Init ();        } private void Init () {ImageView view = new ImageView (mcontext);        View.setbackgroundresource (R.mipmap.jump);        View.setscaletype (ImageView.ScaleType.FIT_XY);    AddView (view); } @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {mwidth = Measurespec.gets Ize (WidthmeasuRESPEC);  Get viewgroup width mheight = measurespec.getsize (Heightmeasurespec);    Get viewgroup height setmeasureddimension (mwidth, mheight);            Sets the ViewGroup width-height if (mfirst) {Mfirst = false;        BeginAnimation (); }} @Override protected void OnLayout (Boolean changed, int left, int top, int. right, int bottom) {} privat        e void BeginAnimation () {final int height;        if (mcurround% 2 = = 0) {//down height = (int) (-mheight * MATH.POW (0.5, MCURROUND/2));        } else {//up height = (int) (-mheight * MATH.POW (0.5, (Mcurround + 1)/2)); } Animation translateanimation = new Animation () {@Override protected void Applytransformati On (float interpolatedtime, transformation t) {if (mcurround% 2 = = 0) {getchildat (0). l        Ayout (0, (int) (height * (1-interpolatedtime)), mwidth, mheight + height-(int) (Interpolatedtime * height));        } else {getchildat (0). Layout (0, (int) (height * interpolatedtime), mwidth, mheight + (int) (He                ight * interpolatedtime));        }            }        };            if (mcurround% 2 = = 0) {translateanimation.setinterpolator (New Accelerateinterpolator ());        Translateanimation.setduration ((Long) (MTime * MATH.POW (0.5, MCURROUND/2)));            } else {translateanimation.setinterpolator (new Decelerateinterpolator ());        Translateanimation.setduration ((Long) (MTime * MATH.POW (0.5, (Mcurround + 1)/2));        } startanimation (Translateanimation); Translateanimation.setanimationlistener (New Animation.animationlistener () {@Override public void on Animationstart (Animation Animation) {} @Override public void Onanimationend (Animation an                Imation) {mcurround++; if (Mcurround < Mtotalround) {BeginAnimation(); }} @Override public void Onanimationrepeat (Animation Animation) {}})    ; }}
This is the first method, we have customized the control, but also in the applytransformation to do the calculation, and then think about the next, in fact, no need to use a custom control, not to calculate, but also can be implemented, the idea is almost, the only difference is that we can use the property animation, Directly with the Objectanimator Offloat method to move the picture on the line, here because the idea is consistent, I put the code directly:

First declare a layout file Jump_layout.xml:

<?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/res/ Android "    android:orientation=" vertical "android:layout_width=" match_parent "    android:layout_height=" Match_parent ">    <imageview        android:id=" @+id/move "        android:layout_width=" Match_parent        " android:layout_height= "Match_parent"        android:src= "@mipmap/jump"        android:scaletype= "Fitxy"        /> </LinearLayout>
After you have finished declaring the Java class Jumpactivity.java:
public class Jumpactivity extends Activity {private ImageView view;    private int mheight;    private int totalround = 10;    private int curround = 0;    private int time = 2000;        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (New Bounceview (this, totalround, time));        Setcontentview (r.layout.jump_layout);    View = (ImageView) Findviewbyid (r.id.move);        } @Override public void Onwindowfocuschanged (Boolean hasfocus) {super.onwindowfocuschanged (hasfocus);            if (hasfocus) {rect outrect = new Rect ();            GetWindow (). Findviewbyid (window.id_android_content). Getdrawingrect (Outrect);            Mheight = Outrect.height ();        Begintransanimation ();        }} private void Begintransanimation () {final int height;        if (curround% 2 = = 0) {//down height = (int) (-mheight * MATH.POW (0.5, CURROUND/2)); } else {Height = (int) (-mheight * MATH.POW (0.5, (Curround + 1)/2));        } Float from = 0;        float to = 0;            if (curround% 2 = = 0) {from = height;        to = 0;            } else {from = 0;        to = height;        } objectanimator Animator = Objectanimator.offloat (view, "Translationy", from, to);        Animator.setinterpolator (New Accelerateinterpolator ()); Animator.addlistener (New Animator.animatorlistener () {@Override public void Onanimationstart (Animat                or animation) {} @Override public void Onanimationend (Animator animation) {                curround++;                if (Curround <= totalround) {begintransanimation ();            }} @Override public void Onanimationcancel (Animator animation) {}  @Override public void Onanimationrepeat (Animator animation) {          }        });            if (curround% 2 = = 0) {animator.setinterpolator (New Accelerateinterpolator ());        Animator.setduration ((Long) (Time * MATH.POW (0.5, CURROUND/2)). Start ();            } else {animator.setinterpolator (new Decelerateinterpolator ());        Animator.setduration ((Long) (Time * MATH.POW (0.5, (Curround + 1)/2)). Start (); }    }}


SOURCE download





Android Image Bounce Animation

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.