Class Animation and its subclasses

Tap the screen and watch the red disk move. The white area is a BackgroundView object, and the disk is a LittleView object. (Actually, the LittleView is more than just the disc. It is the square area that barely encloses the disk.) The BackgroundView has to be a subclass of ViewGroup such as RelativeLayout in order for us to add the LittleView to the BackgroundView. The BackgroundView imposes a size and initial position on the LittleView.

The BackgroundView is touch sensitive because we plugged a View.OnTouchListener into it. The LittleView moves because the View.OnTouchListener starts to animate the LittleView with an Animation object. The Animation object belongs to a subclass of Animation named TranslateAnimation. During a three-second interval, the TranslateAnimation gradually changes the location where the LittleView is displayed.

But the TranslateAnimation has no effect on the actual x and y fields of the LittleView, i.e., on the values that would be returned by the getX and getY methods of the LittleView. To change these values, we have to plug an Animation.AnimationListener into the TranslateAnimation. The onAnimationEnd method of the listener calls the LittleView’s layout method to update the LittleView’s x and y.

We have to make our own copy of the MotionEvent passed to onTouch because the original object might have been changed by the time we got around to using it.

See View Animation.

Source code in Animation.zip

  1. MainActivity.java
  2. BackgroundView.java
  3. LittleView.java
  4. activity_main.xml: unused.
  5. AndroidManifest.xml: untouched.
  6. build.gradle (Module: app)

Create the project

Create classes BackgroundView and LittleView. Edit BackgroundView.java to make the class a subclass of RelativeLayout.

In the Android Studio project view, remove the files app/res/values/attrs_background_view.xml and app/res/values/attrs_little_view.xml from the project to avoid having two resources with the same name. Then remove app/res/layouts/sample_background_view.xml and app/res/layouts/sample_little_view.xml because they use resources created in the files we removed earlier.

TranslateAnimations in ApiDemos

  1. Graphics/AnimateDrawables
    1. app/java/com.example.android.apis/graphics/AnimateDrawables.java
      Class AnimateDrawables is a subclass of class GraphicsActivity. The nested class AnimateDrawables.SampleView creates a Drawable object and an infinite loop TranslateAnimation and puts both of them into an AnimateDrawable object.

    2. app/java/com.example.android.apis/graphics/GraphicsActivity.java
      Class GraphicsActivity is a subclass of class Activity.

    3. app/java/com.example.android.apis/graphics/AnimateDrawable.java
      Class AnimateDrawable is a subclass of class ProxyDrawable.

    4. app/java/com.example.android.apis/graphics/ProxyDrawable.java
      Class ProxyDrawable is a subclass of class Drawable.

    5. app/res/drawable/beach.jpg

  2. Views/Animation/Interpolators
    1. app/java/com.example.android.apis/view/Animation3.java
      Class Animation3 is a subclass of class Activity.

    2. app/res/layout/animation_3.xml
      The layout file contains two TextViews and a Spinner in a vertical LinearLayout.

    3. The files simple_spinner_item.xml and simple_spinner_dropdown_item.xml are in the directory ~/Library/Android/sdk/platforms/android-22/data/res/layout on your Mac or PC.

    4. The files accelerate_interpolator.xml, decelerate_interpolator.xml, accelerate_decelerate_interpolator.xml, etc., are in the directory ~/Library/Android/sdk/platforms/android-22/data/res/anim on your Mac or PC.

Things to try

  1. What hapens (or fails to happen) if onAnimationEnd doesn’t call layout?

  2. Change the animation’s LinearInterpolator into an AccelerateDecelerateInterpolator or an OvershootInterpolator.

  3. Instead of moving the LittleView, make it fade out. Replace the animation object with
                             //from totally opaque to totally transparent
                             AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0f);
    
    In onAnimationEnd, replace the call to layout with
                                    littleView.setAlpha(0f);
    
    For dramatic effect, increase the duration of the animation to 3000 milliseconds. Change the orientation of the device (portrait to landscape) to destroy and re-create the Activity object, which will destroy and recreate the View objects.

  4. Do the translation and fade at the same time. Replace the animation object with the following.
                             TranslateAnimation translateAnimation =
                                     new TranslateAnimation(0f, toXDelta, 0f, toYDelta);
                             AlphaAnimation alphaAnimation = new AlphaAnimation(1f, 0f);
    
                             AnimationSet animationSet = new AnimationSet(true);
                             animationSet.addAnimation(translateAnimation);
                             animationSet.addAnimation(alphaAnimation);
                             animationSet.setDuration(3000L);
    
    			//Initialize the animationSet and give it a listener.
                            littleView.startAnimation(animationSet);
    
    In onAnimationEnd, call layout and setAlpha.

  5. Try a ScaleAnimation or a RotateAnimation.