Bouncing a ball on Android's canvas

Enterprise app developer William J. Francis has fun with Android's animation classes in his bouncing ball tutorial.

Regular readers of my App Builder posts know how much I enjoy taking a break from my day gig as an Android enterprise app developer and playing around with the multimedia capabilities of Google's operating system. I particularly enjoy Android's animation capabilities, and getting to draw directly to the canvas object.

With the release of Android 4.1 (Jelly Bean), Google did a lot of work under the hood to improve the underlying framework that drives the animation, not just in terms of speed but also in the overall smoothness and consistency of visual elements. Getting the opportunity to see the updated animation engine firsthand on my Nexus S proved a perfect excuse for me to write a bouncing ball tutorial.

While I wrote this tutorial with Android 4.1 in mind, there is nothing that is 4.1 specific. Running it on an older device simply means you won't get to see the souped up Android animation engine in action. You can follow along with the step-by-step outline below, or download and import the entire project.

1. Create a new Android project in Eclipse. Target Android 1.6 or higher. Don't forget to rename the startup activity to, along with the associated layout resource.

2. Because we will be drawing the entire canvas ourselves, we will want to handle orientation ourselves as well. This is done by modifying the activity in the AndroidManifest.xml file.


<manifest xmlns:android=""
    android:versionName="1.0" >
        android:targetSdkVersion="15" />
        android:theme="@style/AppTheme" >
            android:screenOrientation="portrait" android:configChanges="orientation|keyboardHidden"
            android:label="@string/title_activity_main" >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
3. The application uses an image to represent our ball. You can use any image you like, and it doesn't have to be round. I chose the image of a tennis ball (Figure A), which I then saved into the /res/drawable folder. Figure A

4. Next we want to define our /res/layout/main.xml file. You will see I've only defined a single custom view; this is a class we will be creating shortly.


<LinearLayout xmlns:android=""

5. It turns out we can use the auto generated file exactly as is.

package com.authorwjf.bounce;

import android.os.Bundle;

public class Main extends Activity {
    public void onCreate(Bundle savedInstanceState) {

6. What remains is to create our custom view class, The class consists of a constructor, a runnable, and the on draw override. There is no tricky math or physics involved for our bouncing ball — I'm simply detecting when it hits an edge and reversing the direction.

package com.authorwjf.bounce;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.ImageView;
public class AnimatedView extends ImageView{
        private Context mContext;
        int x = -1;
        int y = -1;
        private int xVelocity = 10;
        private int yVelocity = 5;
        private Handler h;
        private final int FRAME_RATE = 30;

public AnimatedView(Context context, AttributeSet attrs)  {
                super(context, attrs);
                mContext = context;
                h = new Handler();
         private Runnable r = new Runnable() {
                 public void run() {
         protected void onDraw(Canvas c) {
                 BitmapDrawable ball = (BitmapDrawable) mContext.getResources().getDrawable(R.drawable.ball);
             if (x<0 && y <0) {
                 x = this.getWidth()/2;
                 y = this.getHeight()/2;
             } else {
                 x += xVelocity;
                 y += yVelocity;
                 if ((x > this.getWidth() - ball.getBitmap().getWidth()) || (x < 0)) {
                         xVelocity = xVelocity*-1;
                 if ((y > this.getHeight() - ball.getBitmap().getHeight()) || (y < 0)) {
                         yVelocity = yVelocity*-1;
            c.drawBitmap(ball.getBitmap(), x, y, null);
            h.postDelayed(r, FRAME_RATE);
The screen shots are static, so in order to enjoy the bounce effect you will need to load the application to a device (Figure B). It will run on the emulator, but the animations are more impressive on an actual device — that goes double if you are lucky enough to have a device running Jelly Bean. Figure B

With each iteration of Android things just keep getting better. I can't wait to see what Google has in store for us next.


William J Francis began programming computers at age eleven. Specializing in embedded and mobile platforms, he has more than 20 years of professional software engineering under his belt, including a four year stint in the US Army's Military Intellige...

Editor's Picks