Android: Leaf fall-like animation using property animators

In the previous tutorial we explained how property animations work in general. Now we’ll go even further and explain how to create a property animation that would create leaf-falling-like effect for an ImageView in which we’ll, apparently put images of leaves. For that purpose we need few images that represent leaves.

We found the ones we use in the example somewhere on the net, hopefully not infringing any designer’s work:

If you don’t have anything better, get this images and use them.

When you imagine a falling leaf represented in digital context you can notice three things:

  • the leaf is falling down
  • the leaf is rotating around its axes at some angle
  • the leaf is making curve movement

These three properties would make the effect of a leaf falling down flown by the wind, taken off the tree. One thing that at this point we won’t implement is the curvic transformation since we plan to create separate tutorial about it, as extension to this one.

So we would need to create translation and rotation, putting some more logics here and there.

In Android sense, as we mentioned earlier the leaves would be ImageView objects. They would be created randomly and added to the root layout right before the animation starts. So we’ll need some timer that would knock-off the animation of a single leaf. Let’s say that we want new leaf every 5 seconds. So we’ll need timer that would send empty message, handled by a Handler object. When the message is handled (received), we get random leaf from a set of leaves (Drawables), create ImageView object and put the drawable as its contents, and add the imageview to the root layout of the activity. Then we call a method which in our case is named ‘startAnimation’ that would accept one ImageView object as parameter which will be animated. We do this in this way so that we leave space in the ‘startAnimation’ method where the ViewAnimator would be create, initialized and started, and also its listener.

Let’s go again step by step. Let’s create the Handler object first:

private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    int viewId = new Random().nextInt(LEAVES.length);
                    Drawable d = getResources().getDrawable(LEAVES[viewId]);
                    LayoutInflater inflate = LayoutInflater.from(FallAnimationActivity.this);
                    ImageView leafImageView = (ImageView) inflate.inflate(R.layout.ani_image_view, null);
                    leafImageView.setImageDrawable(d);
                    mRootLayout.addView(leafImageView);
                                       
                    LayoutParams animationLayout = (LayoutParams) leafImageView.getLayoutParams();
                    animationLayout.setMargins(0, (int)(-150*mScale), 0, 0);
                    animationLayout.width = (int) (60*mScale);
                    animationLayout.height = (int) (60*mScale);
                    
                    startAnimation(imageView);
            }
    };

The leafImageView object is inflated from XML so that we don’t have to create it programmatically, mScale is global field holding the density of the screen (used on few other places in the code, that’s why globally declared). After we add the leafImageView to the root layout we’ll programmatically set its top margin to 150dp in minus only to position it above the visible area of the screen. We create TimerTask like this:

private class AnimTimerTask extends TimerTask {
            @Override
            public void run() {
                    mHandler.sendEmptyMessage(0x001);
            }
    }

and the TimerTask is executed like this, in our case in the onCreate method of the Activity:

new Timer().schedule(new AnimTimerTask(), 0, 5000);

This means, create new imageview every 5 seconds, add it to the root layout and start animation on it.

Now back to the logic of the animation. As we previously mentioned we need a to translate to the bottom and side (x/y) and minor rotate animation. Both pivots (x and y) are the center of the axis, so the center of the leaf imageview.

The delay before the animation starts is again calculated randomly as value between 0 and 6000 (milliseconds). The animator would be ofFloat from 0 to 1.

For now, we set the animation to last for 10 seconds (10000 ms). That might be little fast so you can increase this value as you wish.

What happens in the AnimatorUpdateListener is the following: The final ‘x’ position of the leaf imageview would be calculated as random value from 0 (left of the screen) and display’s width (right of the screen). Any point between this would be the ‘x’ final position. The final ‘y’ position of the leaf imageview would be display’s height/bottom, plus 150dp just to make the view not stop in the visible area. I like to make it fall to some point of display’s height + 10dp which would look just as if the leaf has fallen on the ground. This time, we make the leaf dissapear in the void of the screen.

So now we have an imageview that goes from top to bottom where the x final position is random. But we miss 2 more things (rotation + curve animation) out of which we decided to implement only one more, the rotation. Let’s imagine the wind is not that strong so we need tremble-like effect for the leaf. An angle of 50 to 100 would be enough for this to take effect. One general rule to implement this would be this practice:

Min + (int)(Math.random() * ((Max - Min) + 1))

In our case that’d be:

50 + (int)(Math.random() * 101)

onAnimationUpdate is called till every last frame is done. Rotation and Translation are set here. Lastly we start the animator. Here is the whole method:

public void startAnimation(final ImageView leafImageView) {

    leafImageView.setPivotX(leafImageView.getWidth()/2);
    leafImageView.setPivotY(leafImageView.getHeight()/2);

    long delay = new Random().nextInt(6000);

    final ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
    animator.setDuration(10000);
    animator.setInterpolator(new AccelerateInterpolator());
    animator.setStartDelay(delay);

    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    
            int movex = new Random().nextInt(mDisplaySize.right);
            int angle = 50 + (int)(Math.random() * 101);
                    
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                    float value = ((Float) (animation.getAnimatedValue())).floatValue();
                            
                    leafImageView.setRotation(angle*value);
                    leafImageView.setTranslationX((movex-40)*value);
                    leafImageView.setTranslationY((mDisplaySize.bottom + (150*mScale))*value);
            }
    });

    animator.start();
}

When we run this application we’re supposed to see something like this:

We use this animation for our latest project which is in its latest polishing process.

Also, download the sources and see if we’ve missed something or made a mistake explaining the code.

Reference: Android: Leaf fall-like animation using property animators from our JCG partner Aleksandar Balalovski at the 2Dwarfs blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

2 Responses to "Android: Leaf fall-like animation using property animators"

  1. Aditya says:

    ur code, is not running in Emulator.
    it shows , unfortunately view animation ,example has stopped

  2. Umar says:

    Thanx man… well done 1000+

Leave a Reply


6 − = two



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close