Android Application Development : Drawing 2D and 3D Graphics - Bling (part 2) - Animation - Transition animation

1/5/2014 12:16:24 AM

1. Shadows, Gradients, and Filters

PathEffect, MaskFilter, ColorFilter, Shader, and ShadowLayer are all attributes of Paint. Anything drawn with Paint can be drawn under the influence of one or more of these transformations. The top several widgets in Figure 1 give examples of some of these effects.

Widgets 1 and 2 demonstrate shadows. Shadows are currently controlled by the setShadowLayer method. The arguments, a blur radius and X and Y displacements, control the apparent distance and position of the light source that creates the shadow, with respect to the shadowed object. Although this is a very neat feature, the documentation explicitly warns that it is a temporary API. However, it seems unlikely that the setShadowLayer method will completely disappear or even that future implementations will be backward-incompatible.

The Android toolkit contains several prebuilt shaders. Widgets 3 and 4 demonstrate one of them, the LinearGradient shader. A gradient is a regular transition between colors that might be used, for example, to give a page background a bit more life, without resorting to expensive bitmap resources.

A LinearGradient is specified with a vector that determines the direction and rate of the color transition, an array of colors through which to transition, and a mode. The final argument, the mode, determines what happens when a single complete transition through the gradient is insufficient to cover the entire painted object. For instance, in widget 4, the transition is only 15 pixels long, whereas the drawing is more than 100 pixels wide. Using the mode Shader.TileMode.Mirror causes the transition to repeat, alternating direction across the drawing. In the example, the gradient transitions from blue to green in 15 pixels, then from green to blue in the next 15, and so on across the canvas.

2. Animation

The Android UI toolkit offers several different animation tools. Transition animations—which the Google documentation calls tweened animations—are subclasses of android.view.animation.Animation: RotateAnimation, TranslateAnimation, ScaleAnimation, etc. These animations are used as transitions between pairs of views. A second type of animation, subclasses of⁠able, can be put into the background of any widget to provide a wide variety of effects. Finally, there is full-on animation, on top of a SurfaceView that gives you full control to do your own seat-of-the-pants animation.

Because both of the first two types of animation, transition and background, are supported by View—the base class for all widgets—every widget, toolkit, and custom will potentially support them.

2.1. Transition animation

A transition animation is started by calling the View method startAnimation with an instance of Animation (or, of course, your own subclass). Once installed, the animation runs to completion: transition animations have no pause state.

The heart of the animation is its applyTransformation method. This method is called to produce successive frames of the animation. Example 3 shows the implementation of one transformation. As you can see, it does not actually generate entire graphical frames for the animation. Instead, it generates successive transformations to be applied to a single image being animated.

Example 3. Transition animation
protected void applyTransformation(float t, Transformation xf) {
Matrix xform = xf.getMatrix();

float z = ((dir > 0) ? 0.0f : -Z_MAX) - (dir * t * Z_MAX);;
camera.rotateZ(t * 360);
camera.translate(0.0F, 0.0F, z);

xform.preTranslate(-xCenter, -yCenter);
xform.postTranslate(xCenter, yCenter);

This particular implementation makes its target appear to spin in the screen plane (the rotate method call), and at the same time, to shrink into the distance (the translate method call). The matrix that will be applied to the target image is obtained from the Transformation object passed in that call.

This implementation uses camera, an instance of the utility class Camera. The Camera class—not to be confused with the camera in the phone—is a utility that makes it possible to record rendering state. It is used here to compose the rotation and translations transformations into a single matrix, which is then stored as the animation transformation.

The first parameter to applyTransformation, named t, is effectively the frame number. It is passed as a floating-point number between 0.0 and 1.0, and might also be understood as the percent of the animation that is complete. This example uses t to increase the apparent distance along the Z-axis (a line perpendicular to the plane of the screen) of the image being animated, and to set the proportion of one complete rotation through which the image has passed. As t increases, the animated image appears to rotate further and further counter-clockwise and to move farther and farther away, along the Z-axis, into the distance.

The preTranslate and postTranslate operations are necessary in order to translate the image around its center. By default, matrix operations transform their target around the origin. If we did not perform these bracketing translations, the target image would appear to rotate around its upper-left corner. preTranslate effectively moves the origin to the center of the animation target for the translation, and postTranslate causes the default to be restored after the translation.

If you consider what a transition animation must do, you’ll realize that it is likely to compose two animations: the previous screen must be animated out and the next one animated in. Example 3 supports this using the remaining, unexplained variable dir. Its value is either 1 or –1, and it controls whether the animated image seems to shrink into the distance or grow into the foreground. We need only find a way to compose a shrink and a grow animation.

This is done using the familiar Listener pattern. The Animation class defines a listener named Animation.AnimationListener. Any instance of Animation that has a nonnull listener calls that listener once when it starts, once when it stops, and once for each iteration in between. Creating a listener that notices when the shrinking animation completes and spawns a new growing animation will create exactly the effect we desire. Example 4 shows the rest of the implementation of the animation.

Example 4. Transition animation composition
public void runAnimation() {
animateOnce(new AccelerateInterpolator(), this);

public void onAnimationEnd(Animation animation) { Runnable() {
public void run() {
new RotationTransitionAnimation(-1, root, nextView, null)
.animateOnce(new DecelerateInterpolator(), null);
} });

void animateOnce(
Interpolator interpolator,
Animation.AnimationListener listener)

The runAnimation method starts the transition. The overridden AnimationListener method, onAnimationEnd, spawns the second half. Called when the target image appears to be far in the distance, it hides the image being animated out (the curView) and replaces it with the newly visible image, nextView. It then creates a new animation that, running in reverse, spins and grows the new image into the foreground.

The Interpolater class represents a nifty attention to detail. The values for t, passed to applyTransformation, need not be linearly distributed over time. In this implementation the animation appears to speed up as it recedes, and then to slow again as the new image advances. This is accomplished by using the two interpolators: Accel⁠era⁠teInter⁠polator for the first half of the animation and DecelerateInterpola⁠tor for the second. Without the interpolator, the difference between successive values of t, passed to applyTransformation, would be constant. This would make the animation appear to have a constant speed. The AccelerateInterpolator converts those equally spaced values of t into values that are close together at the beginning of the animation and much further apart toward the end. This makes the animation appear to speed up. Decelera⁠teInterpolator has exactly the opposite effect. Android also provides a CycleInterpo⁠lator and LinearInterpolator, for use as appropriate.

Animation composition is actually built into the toolkit, using the (perhaps confusingly named) AnimationSet class. This class provides a convenient way to specify a list of animations to be played, in order (fortunately not a Set: it is ordered and may refer to a given animation more than once). In addition, the toolkit provides several standard transitions: AlphaAnimation, RotateAnimation, ScaleAnimation, and Transla⁠teA⁠nima⁠tion. Certainly, there is no need for these transitional animations to be symmetric, as they are in the previous implementation. A new image might alpha fade in as the old one shrinks into a corner or slide up from the bottom as the old one fades out. The possibilities are endless.

  •  Developing BlackBerry Tablet Applications : OS Interactions - Native QNX Components
  •  Developing BlackBerry Tablet Applications : OS Interactions - Screen Options
  •  Developing BlackBerry Tablet Applications : OS Interactions - StageWebView
  •  Developing BlackBerry Tablet Applications : OS Interactions - Splash Screen
  •  Developing BlackBerry Tablet Applications : OS Interactions - Open in Browser
  •  iPhone Developer : Assembling Views and Animations - Transforming Views
  •  iPhone Developer : Assembling Views and Animations - Randomly Moving a Bounded View
  •  iPhone Developer : Assembling Views and Animations - Working with View Frames (part 2) - Other Utility Methods
  •  iPhone Developer : Assembling Views and Animations - Working with View Frames (part 1) - Adjusting Sizes , CGRects and Centers
  •  iPhone Developer : Assembling Views and Animations - View Geometry
    Most View
    Microsoft SharePoint 2010 Web Applications : Presentation Layer Overview - Ribbon (part 1)
    The Cyber-athletic Revolution – E-sports’ Era (Part 1)
    Windows Server 2003 : Implementing Software Restriction Policies (part 4) - Implementing Software Restriction Policies - Creating a Path Rule, Designating File Types
    Sql Server 2012 : Hierarchical Data and the Relational Database - Populating the Hierarchy (part 1)
    Two Is Better Than One - WD My Cloud Mirror
    Programming ASP.NET 3.5 : Data Source-Based Data Binding (part 3) - List Controls
    Windows 8 : Configuring networking (part 5) - Managing network settings - Understanding the dual TCP/IP stack in Windows 8, Configuring name resolution
    Nikon Coolpix A – An Appealing Camera For Sharp Images (Part 2)
    Canon PowerShot SX240 HS - A Powerful Perfection
    LG Intuition Review - Skirts The Line Between Smartphone And Tablet (Part 2)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
    Top 10
    Review : Acer Aspire R13
    Review : Microsoft Lumia 535
    Review : Olympus OM-D E-M5 Mark II
    TomTom Runner + MultiSport Cardio
    Timex Ironman Run Trainer 2.0
    Suunto Ambit3 Peak Sapphire HR
    Polar M400
    Garmin Forerunner 920XT
    Sharepoint 2013 : Content Model and Managed Metadata - Publishing, Un-publishing, and Republishing
    Sharepoint 2013 : Content Model and Managed Metadata - Content Type Hubs