The existing Android animation frame is built on the view level, there is an interface startanimation in the view class to start the animation, the Startanimation function will pass a Animation class parameter to the view, this Anima tion is used to specify which animations we use, existing animations have translation, scaling, rotation, and alpha transformations. If more complex effects are needed, we can also combine these animations, which are discussed below.
To understand how Android animations are drawn, let's start by understanding how Android View is organized together and how they draw their own content. Each window is a view tree, the following is an example of the Tab control window we wrote in Android_tabwidget_tutorial.doc, the window View tree obtained through the Android tool Hierarchyviewer as shown:
Figure 2. Interface View structure
Figure 3. Interface view structure and display corresponding figure
actually this picture is not complete, did not put Rootview and Decorview draw out, Rootview only one child is Decorview, Here the entire view Tree is a Decorview view, which is from the Android1.5/frameworks/base/core/res/res/layout/screen_title.xml this layout file inf Alte out, interested readers can refer to the Frameworks\policies\base\phone\com\android\internal\policy\imp\phonewindow.java The code for the Generatelayout function section. We can modify the layout files and code to do some cool things, elephant the Windows Zoom/off button and so on. The framelayou in the following section of the title window is intended to allow programmers to set the window content required by the user through Setcontentview. Because the layout of the entire view is a tree, it is always drawn with each view as a tree structure. The draw function in Viewroot.java calls Mview.draw (canvas) When the canvas is ready, where MView is the Decorview that is set when Viewroot.setview is called. Then take a look at the draw function in View.java:
The recursive drawing of the entire window requires the following steps to be performed sequentially:
- Draw the background;
- If necessary, save the canvas layer for fade-in or fade-out preparation;
- Drawing the contents of the View itself, by calling the View.ondraw (canvas) function, through which we should be able to see the importance of OnDraw function overloading, onDraw functions such as drawing lines/circles/text will call the corresponding function in canvas.
- Draw your own child (often also a view system), implemented by Dispatchdraw (canvas), see the code in Viewgroup.java,dispatchdraw->drawchild-> The call procedure for Child.draw (canvas) is used to ensure that each child view's draw function is called, allowing the content of all view in the entire view tree to be drawn through this recursive invocation. Before invoking the draw function of each sub-view, the drawing position of the view to be drawn is toggled in the canvas through the Translate function call, and all view in the window is a shared canvas object
- If necessary, draw the fade-related content and restore the layer on which the saved canvas is located (layer)
- Paint the decorated content (for example, scroll bars)
When a childview is to be redrawn, it calls its member function invalidate () function will notify it parentview this childview to redraw, this process has been traversing up to Viewroot, when Viewroot received this notification will call on the The draw function in the viewroot mentioned in the polygon to finish drawing. View::ondraw () has a canvas parameter canvas, the canvas as the name implies is the place to draw things, Android will set a canvas for each view, view can call the method of canvas, such as: DrawText, Drawbitmap, DRA WPath and so on to draw the content. Each Childview canvas is set by its parentview, Parentview adjusts the canvas according to the layout of the Childview within it, where one of the properties of the canvas is to define and childview the relevant coordinate system, by default the horizontal axis is the X axis, from Left to right, the value gradually increases, the vertical axis is the Y axis, from top to bottom, the value increases gradually, see:
Figure 4. Window coordinate system
Android animation is done by Parentview to constantly adjust the childview canvas coordinate system, the following is a translation animation to do the example, see 5, assuming that at the beginning of the animation Childview in Parentview initial position at (100,200), which Parentview will set the Childview canvas based on this coordinate, and in Parentview Dispatchdraw it finds Childview has a panning animation, and the current translation position is (100, 200), so it calls the canvas The number traslate (100, 200) tells Childview to start painting in this position, which is the first frame of the animation. If Parentview found that Childview has animation, it will constantly call invalidate () This function, which will cause oneself will continue to redraw, will continue to call Dispatchdraw this function, which produces the animation of the subsequent frames, when the re-entry Dispatchdraw, Parentview produces a translation position of the second frame (500, 200) based on the panning animation, and then proceeds with the above operation, then produces a third frame, frame fourth, until the animation is finished. The specific algorithm description is shown in Listing 2:
Listing 2. Algorithm
[CPP]View Plaincopy
- Dispatchdraw ()
- {
- ....
- Animation a = Childview.getanimation ()
- transformation tm = a.gettransformation ( );
- use tm to set childview " s canvas;
- Invalidate ();
- ....
- }
Figure 5. Panning Animations
above is a translation animation as an example to illustrate the production process of animation, which involves two important types, Animation and transformation, These two classes are the main classes that implement animations, and Animation mainly defines properties such as the start time, duration, and repetition of the animation, which have two important functions: Gettransformation and Applytransformation, in Gettransformation Animation will generate a series of difference points based on the properties of the animation, and then pass these difference points to applytransformation, which will generate different transformation based on these points. The transformation contains a matrix and alpha value, which is used to translate, rotate, and scale the animation, and the alpha value is used to do Alpha animation (the Alpha animation is equivalent to constantly changing the transparency or color to achieve animation), With the translation matrix above as an example, when calling Dispatchdraw, Gettransformation is called to get the current transformation, and the matrix in this transformation is as follows:
Figure 6. Matrix Transformation Diagram
So the specific animation only need to overload applytransformation this function, the class level diagram is as follows:
Figure 7. Animation class inheritance Diagram
Each animation overloads the parent class's Applytransformation method, which is called by the parent class's Gettransformation method. In addition, each animation also has a initialize method to complete the initialization work.
Users can define their own animation classes, simply inherit the Animation class, and then overload the Applytransformation function. The behavior of the animation is mainly determined by the difference point, for example, we want to start the animation is gradually accelerated or gradually slow, or fast after slow, or uniform, these functions are mainly implemented by the difference function, Android provides a interpolator base class, This function is used when you want to implement a speed that can overload its function getinterpolation and generate a difference point in the Animation gettransformation.
Figure 8. Interpolator inheritance Diagram
From the analysis of the animation mechanism above, we can see that the animation of a view is not done by himself but by its parent view, and all of us should note that the animation in the animated example program of the TextView rotation week above is not drawn by TextView, but by its parent view To do. Findviewbyid (r.id.textview01). Startanimation (ANIM) This code is actually for this TextView set a animation, instead of the actual animation to draw, the code is as follows:
[CPP]View Plaincopy
- public   void startanimation (Animation animation)
- {
- Animation.setstarttime (Animation.start_on_first_frame);
- Setanimation (animation); Invalidate ();
- }
The above is the principle of Android animation framework, understand the principle of our development can clearly grasp the animation of how each frame is generated, so as to facilitate the development and debugging. It gives the animation's play/draw to the parent view to process rather than let the child view itself to draw, this from a higher level to control the way to make the animation mechanism into an easy-to-use framework, if the user to be used in a View of animation, only need to be specified in the XML description file or code can be, Thus, the implementation of the animation and the rendering of the View itself (like the text in the TextView) separated, played a reduction in coupling and improve the usability of the effect.