Android Animations 3D flip
In this post we are going to look at how to create a 3D flip animation, with a FrameLayout.
In the first few posts I've written on Android and animations we have only looked at the predefined animations supplied in the android.view.animations package. In fact we've only used the translate animation, but as I've mentioned before there are also rotate, scale and alpha animations.
I've used some firefox image icons to animate, they are part of a very good and free icon set that can be found
here
. If you just want the images i've used they can be found
here
and
here
. Download these images and place them in the res/drawable folder of the Flip3d project.
This is the frame layout and we've specified that it contains two child views, first_view and second_view. Lets Create these views. In res/layout create two files first_view.xml and second_view.xml. The first view file needs to look like this:
And second_view.xml contains this xml:
These two views are almost identical and only contain two different images that we will flip between.Now we have our layouts defined we need to write some Java to implement our 3d flip. Create a Java class called Flip3dAnimation in the com.example.flip3d package and cut and paste in this code:
In the first few posts I've written on Android and animations we have only looked at the predefined animations supplied in the android.view.animations package. In fact we've only used the translate animation, but as I've mentioned before there are also rotate, scale and alpha animations.
In this tutorial i want to take a further look at animations and how we can created our own custom animations using the Android library. I've going to base the tutorial on some of the examples that can be found in the samples folders that are downloaded with the android SDK. These are some great examples, but unfortunately they seem to lack a little on documentation and explanation as to how, and what, the code is doing. Hopefully by the end of this tutorial things should be a little clearer.
Before we start here's an example of the end result of our 3d flip:
So lets get started. First Create a new Android project in Eclipse with these setting:
Project name: Flip3d
Application Name: Flip3d
package name: com.example.flip3d
Activity: Flip3d
Lets start with defining a layout that we can use. As I mentioned we are going to use a FrameLayout. As with the ViewFlipper the FrameLayout can contain a number of child views, but unlike ViewFlipper, FrameLayout stacks it's child views on top of each other with the most recent added child on top. Initially without any intervention all the child views of the FrameLayout are visible, but don't worry about that for now, we will solve this at a later stage. In the FrameLayout we will define two child views, these are the views that we will animate between. In res/layout edit the main.xml file so that it looks like this:
This class extends the Animation class and implements the applyTransformation method. Each Animation has a transformation object that Defines the transformation to be applied at a point in time of the Animation. When this animation is running the applyTransformation method will be called a number of times to allow us to calculate the transformation to be applied. Each time applyTransformation is called the interpolation value passed in will be increased slightly starting at 0 and ending up at 1. So our float 'degree' at line LINE NUMBER will increase slightly each time this method is called.
The main steps that happen in the applyTransformation are:
Calculate the degrees rotation for the current transformation
Get the tranformation matrix for the Animation
Generate a rotation matrix using camera.rotate(degrees)
Apply that matrix to the Animation transform
Set a pre translate so that the view is moved to the edge of the screen and rotates around it centre and not it's edge
Set a post translate so that the animated view is placed back in the centre of the screen.
Get the tranformation matrix for the Animation
Generate a rotation matrix using camera.rotate(degrees)
Apply that matrix to the Animation transform
Set a pre translate so that the view is moved to the edge of the screen and rotates around it centre and not it's edge
Set a post translate so that the animated view is placed back in the centre of the screen.
Camera in android.graphics
You can see that we also use the android.graphics.Camera class, don't get this confused with camera class in android.hardware which is used to control the Camera on the android device. The Camera class in the android.graphic package is very different, it is used to calculate 3d transformations that can then be applied to animations. This Camera class represents a virtual view as if we were looking at our Android views through a camera. As we move our virtual camera to the left , we have the effect of the android view moving to the right , and if we rotate our virtual camera, we have the effect of rotating our Android view. Here the Camera class is use to calculate a rotate transformation about the Y axis, it does this every time the applyTransformation method is called and so gives each incremental transformation that is needed to give a smooth rotation effect. Camera uses transformation matrices to store and calculate transforms. It's not really necessary to have an in depth knowledge of how transformation matricies work, but a good article on them can be found
here
. The article is based around flash, but the same principles apply.
Now that we've got our rotation animation we need to come up with a plan of how to use it. We currently have two images but just rotating these isn't going to give us the effect we want. So what we need to do is hide the second image and display only the first. We will then rotate this image through 90 degree until it's edge on and we can no longer see it. At this point we will make the first image invisible and the second image visible, we will start the animation of the second image at a 90 degree angle and then roatate round until it is fully visible. To go back from the second to the first image we will just reverse the process.
We'll start with our main Activity class Flip3d.java:
The applyRotation method is fairly straight forward, we find the centre of our image, create a new instance of our Flip3dAnimation, and apply and start it for the visible image. Well, there's a little more yet... As you may have already noticed we've only done half the animation here, from 0 to 90 degrees, we still have another 90 degrees to go, and we still have to swap the images over half way through. So this is were we need an Animation listener, which we are going to call DisplayNextView. Create a class of this name and paste in this code:
You should now have a working flip animation. This technique can also be applied to ViewGroups , so it could be used as a way to transition between different views. There are a few more things that we can do to this animation to improve it such as adding a depth effect, but I'll leave that to another post. Like I mentioned earlier, this example is based on the samples that are in the downloadable SDK files, so have a look at these samples as well.