Click here to Skip to main content
Click here to Skip to main content
Go to top

Animation with SurfaceView

, 5 Sep 2013
Rate this:
Please Sign up or sign in to vote.
This article give a solution to develop Animation by using Canvas, Paint and SurfaceView

Introduction

In fact you maybe got some requirement likes that: make a list auto scroll, the center image will be auto scale up...With the requirements like that, it seems there is no View in Android can be applied to resolve, and you must customize by your self.

Normally, the most importance point I think almost developer must resolve is View animation.

Today, I will guide a solution which is used to customize View in Android development, it is Animation in SurfaceView. I also wrote some article about it, such as, Half Circle List View or Auto Slide List View,...

This article is only my thinking, maybe not a best solution. But I hope I can bring to you a way, to continue with Android customize View.

Background

A lot of developers think that, SurfaceView is really special in Android. No, it is a normal View only. The different point is it can be drawn in background thread (onDraw() of View must be executed in UI thread). Summary, the way to executed animation will executed in a thread run continuously 2 functions below

  • Update the view's properties coordinate, alpha, scale.
  • Draw view with updated properties.

To do it, using Canvas and Paint. I will give an example with Bitmap for easy in thinking with below code:

canvas.drawBitmap(mBitmap, x, y, paint);

Translate mBitmap, update x, y

Fade out or fade in mBitmap, update alpha of paint

paint.setAlpha((int) alpha);  

Scale mBitmap update scale property of canvas.

canvas.scale(scaleValue, 1, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);  

Rotate mBitmap, you can update matrix value. Please refer hererefer here for more detail.

How about animation?

Base on idea about, if we can give a formula to update mBitmap properties, we can execute animation. Please thinking via simple sample:

Suppose that, from time t1 to time t2, view is translated from x1 to x2. What is the coordinate of view in time t? The formula will be: x = x1 + t * (x2-x1) / (t2-t1)

Using the code

Animation.java

Base on idea above, I made a simple Animation class which is used to calculate the current value, with below properties:

  • mStartValue: The beginning value when animation starting.
  • mEndValue: The final value when animation ending.
  • mDuration: The duration to change value from mStartValue to mEndValue.
  • mStartTime: The time animation starting. At the time animation is started, it is got by System.currentTimeMillis().
  • mEndTime: The time animation ending. mEndTime = mStartTime + mDuration.
The method to get the current value at specified time will be:
public float getCurrentValue(long currentTime) {
   float currentValue = mStartValue + (currentTime)
                * (mEndValue - mStartValue) / mDuration;
   if (currentTime > mEndTime) {
           currentValue = mEndValue;
   }
   return currentValue; 
}   

Extends Animation.java, we have AlphaAnimation, ScaleXAnimation, ScaleYAnimation, TranslateXAnimation, TranslateYAnimation.

To translate bitmap from [x = 0] to [x = screen width] in 3 seconds you can make TranslateXAnimation:

animation = new TranslateXAnimation();
animation.mDuration = 3000;
animation.mStartTime = System.currentTimeMillis();
animation.mEndTime = System.currentTimeMillis() + 3000;
animation.mStartValue = 0;
animation.mEndValue = SCREEN_WIDTH;   

To translate bitmap from [y = 0] to [x = screen height] in 3 seconds you can make TranslateYAnimation:

animation = new TranslateYAnimation();
animation.mDuration = 3000;
animation.mStartTime = System.currentTimeMillis();
animation.mEndTime = System.currentTimeMillis() + 3000;
animation.mStartValue = 0;
animation.mEndValue = SCREEN_HEIGHT;  

To fade in bitmap from alpha = 0 to alpha = 255, make AlphaAnimation

animation = new AlphaAnimation();
animation.mDuration = 3000;
animation.mStartTime = System.currentTimeMillis();
animation.mEndTime = System.currentTimeMillis() + 3000;
animation.mStartValue = 0;
animation.mEndValue = 255;  

To draw bitmap in SurfaceView, base on the animation type to apply the way in Background

if (animation.mType == Type.TranslateX) {
                float currentX = animation.getCurrentValue(System
                        .currentTimeMillis() - animation.mStartTime);
                canvas.drawBitmap(mBitmap, currentX, Y_DEFAULT_COORDINATE,
                        paint);
            } else if (animation.mType == Type.TranslateY) {
                float currentY = animation.getCurrentValue(System
                        .currentTimeMillis() - animation.mStartTime);
                canvas.drawBitmap(mBitmap, X_DEFAULT_COORDINATE, currentY,
                        paint);
            } else if (animation.mType == Type.ScaleX) {
                float currentY = animation.getCurrentValue(System
                        .currentTimeMillis() - animation.mStartTime);
                // canvas.drawBitmap(mBitmap, X_DEFAULT_COORDINATE, currentY,
                // paint);
                canvas.scale(currentY, 1, mBitmap.getWidth() / 2,
                        mBitmap.getHeight() / 2);
                canvas.drawBitmap(mBitmap, X_DEFAULT_COORDINATE,
                        Y_DEFAULT_COORDINATE, paint);
            } else if (animation.mType == Type.ScaleY) {
                float currentY = animation.getCurrentValue(System
                        .currentTimeMillis() - animation.mStartTime);
                // canvas.drawBitmap(mBitmap, X_DEFAULT_COORDINATE, currentY,
                // paint);
                canvas.scale(1, currentY, mBitmap.getWidth() / 2,
                        mBitmap.getHeight() / 2);
                canvas.drawBitmap(mBitmap, X_DEFAULT_COORDINATE,
                        Y_DEFAULT_COORDINATE, paint);
            } else if (animation.mType == Type.Alpha) {
                float alpha = animation.getCurrentValue(System
                        .currentTimeMillis() - animation.mStartTime);
                // canvas.drawBitmap(mBitmap, X_DEFAULT_COORDINATE, currentY,
                // paint);
                paint.setAlpha((int) alpha);
                canvas.drawBitmap(mBitmap, X_DEFAULT_COORDINATE,
                        Y_DEFAULT_COORDINATE, paint);
            }  

History 

20130905: First created.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

huyletran

Vietnam Vietnam
I'm Java developer.
I started Java web coding from 2007 to 2010. After that, I began to develop Android from 2010 to now.
In my thinking, sharing and connecting is the best way to develop.
I would like to study more via yours comments and would like to have relationship with more developers in the world.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 5 Sep 2013
Article Copyright 2013 by huyletran
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid