2D Animation for Android* Series: Comparing and Contrasting Different Ways of Doing the Same Animation Part II

Part II: View Animation

Part I of this series showed how to create various property animations on a view. In Part II we will use view animations to accomplish the same thing. Please see Part I of the series for more information on set up.

Table of Contents

  1. View Animation
    a. View Animation (Non-Set and Set)
    b. View Animation with XML
    c. Custom Animation

View Animation

The following ways of creating animation must be done on a view, whether it is the generic view from the Android API or your own custom extended view class. Note that this will change only where the view is drawn on the screen and not where it will actually be located. For example, a button will appear to move across the screen, but the clickable area of the button will not move with it. You can get around this by writing your own custom animation and having it update the properties instead of applying a transformation matrix to the object. View animations also use an implementation of the AnimationListener interface to do callbacks instead of like an AnimationListenerAdapter class used in property animation, which means you have to include all of its methods even if you don’t need them.

a. View Animation (Non-Set and Set)

You can either nest your view animations or group them together in a set. This allows you to have one start call for all your simultaneous or chained animations. If you do nest them, you will need to set <animation>.setFillAfter to true, so the view stays where it is at the end of the first animation instead of jumping back to the starting point and then starting the next animation. Note that the implementation we are doing here takes advantage of the fact that we are doing the same animation twice, but in reverse the second time by setting repeat count to one and setting the repeat mode to reverse. We could have nested them together instead, but this way is more concise in our case. You can also use the repeat in reverse logic on some of the property animations explained in part one; we opted not to do this as it might interfere with the techniques we were illustrating there. TranslateAnimation and the other view animations are different in that the values they take in are not absolute values but the amount of change to apply at the start and end of the animation. Hence the first value we have put in is 0 as we want it to stay in place at the start of the animation, and then we want it to move half way to the left at the end of animation so –x/2.

public void doViewAnimation(){
     TranslateAnimation transTo= new TranslateAnimation(0, -mLittleChef.getX()/2, 0, 0);
     transTo.setRepeatCount(1);
     transTo.setRepeatMode(Animation.REVERSE);
     transTo.setAnimationListener(new Animation.AnimationListener(){
           @Override
           public void onAnimationEnd(Animation animation) {
                simpleLock=  false;
           }
          @Override
          public void onAnimationStart(Animation animation) { 
               // TODO Auto-generated method stub 
	 } 
          @Override 
          public void onAnimationRepeat(Animation animation) {
              // TODO Auto-generated method stub 
           }
 });
     transTo.setInterpolator(new LinearInterpolator()); 
     transTo.setDuration(mShortAnimationDuration/2); 
     mLittleChef.startAnimation(transTo); 
}
And the view animation set method:


public void doViewAnimationSet(){
     TranslateAnimation transTo= new TranslateAnimation(0, -mLittleChef.getX()/2, 0, 0);
     TranslateAnimation transBack= new TranslateAnimation(0, mLittleChef.getX()/2, 0, 0);
     transTo.setDuration(mShortAnimationDuration/2);
     transBack.setDuration(mShortAnimationDuration/2); 
     transTo.setStartOffset(0); 
     transBack.setStartOffset(transTo.getDuration());
     AnimationSet transSet= new AnimationSet(true);
     transSet.setInterpolator(new LinearInterpolator()); 
     transSet.addAnimation(transTo);
     transSet.addAnimation(transBack);
     transSet.setAnimationListener(new AnimationListener(){
          @Override
          public void onAnimationEnd(Animation animation) {
               simpleLock= false;
          }

          @Override
          public void onAnimationStart(Animation animation) { 
               //  TODO Auto-generated method stub
           } 

          @Override 
          public void onAnimationRepeat(Animation animation) { 
               //  TODO Auto-generated method stub 
          }
     });
     mLittleChef.startAnimation(transSet); 
     //another way to start your set animation:
     //set.setTarget(mLittleChef); 
    //set.start();
     }

b. View Animation with XML

You can also set your animation parameters in an XML file in the res/anim folder. Again, this has similar disadvantages as object animation with XML explained in Part I of the series in that the values are static, making it hard to compensate for different screen sizes. However, for a translation animation, we are choosing the “toXDelta” instead and combining it with being able to use values that end in % (percentage relative to itself) or %p (percentage relative to its parent). This makes it more manageable.

public void doViewAnimationXML(){
     Animation trans = AnimationUtils.loadAnimation(getActivity(), R.anim.view_animation);
     trans.setRepeatCount(1);
     trans.setRepeatMode(Animation.REVERSE);
     trans.setAnimationListener(new AnimationListener(){
          @Override
          public void onAnimationEnd(Animation animation) { 
               simpleLock= false;
          }

          @Override
          public void onAnimationRepeat(Animation animation) {
               // TODO Auto-generated method stub
          } 

          @Override
          public void onAnimationStart(Animation animation) {  
               // TODO Auto-generated method stub 
          } 
     }); 
     mLittleChef.startAnimation(trans); 
}

The view_animation.xml in the res/anim-xhdpi:


<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
     android:duration="2000"
     android:fromXDelta="0"
     android:toXDelta="-15%p"
     android:interpolator="@android:anim/linear_interpolator"
/>

c. Custom View Animation

As mentioned in the view animation overview, here is how you would write your own custom animation to move your actual view and not just where it is drawn. We achieve this by overriding the applyTransformation method and using setX to update with interpolated the value.

public void doCustomAnimation(){ 
     final Float startingPoint= mLittleChef.getX(); 
     Animation animation = new Animation() 
          {
          @Override 
          protected void applyTransformation(float interpolatedTime, Transformation t) { 
               mLittleChef.setX(startingPoint - (int)(startingPoint/2 * interpolatedTime));
	          }

      };

     animation.setAnimationListener(new AnimationListener(){
           @Override 
           public void onAnimationEnd(Animation animation) {
               simpleLock= false; 
           }
          @Override 
          public void  onAnimationRepeat(Animation animation) { 
               // TODO Auto-generated method stub 
          } 
          @Override 
          public void onAnimationStart(Animation animation) { 
               // TODO Auto-generated method stub 

	  }); 

          animation.setInterpolator(new LinearInterpolator()); 
          animation.setRepeatCount(1);
          animation.setRepeatMode(Animation.REVERSE);
          animation.setDuration(mShortAnimationDuration/2);
          mLittleChef.startAnimation(animation);
}

Summary

View animations can give you the capability to animate the transformation of different properties of the view. You can define them individually, in a set, or separately in an XML file. Next up in this blog series are drawables and canvas.

References

http://developer.android.com/guide/topics/graphics/index.html

Part I on Property Animations

https://software.intel.com/en-us/articles/2d-animation-for-android-series-comparing-and-contrasting-different-ways-of-doing-the-same

About the Author

Whitney Foster is a software engineer at Intel in the Software Solutions Group working on scale enabling projects for Android applications.

*Other names and brands may be claimed as the property of others.
**This sample source code is released under the Intel Sample Source Code License Agreement