In the previous articles we have looked at a couple of animation types and the stock interpolators that are available to us. Next we’ll look at the remaining animation types.
You can get the source code for the project that we’re working on here.
We’ve already encountered translate and alpha animations, and there are a couple more: rotate and scale. These are fairly self-explanatory as they allow us to rotate and scale a view respectively. There is a final animation type, known as an Animation Set which allows us to combine animations together. Animation sets are extremely powerful, and allow us to do some quite complex things.
For example, let’s create a new animation that we’ll apply to the button on the second activity. In res/anim/grow_spin.xml:
At the moment, the outer “set” element isn’t actually doing anything as we only have a single child element, but that will change shortly. The “scale” element is going to cause our button to grow by a factor of 8 in both X and Y directions (line 3), from the centre of the screen (line 4), in one second (line 5).
To use this animation, we need to change SecondActivity:
@Override
protected void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
setContentView( R.layout.second );
final Button button = (Button)findViewById( R.id.BackButton );
button.setOnClickListener( new OnClickListener()
{
@Override
public void onClick( View v )
{
Animation animation = AnimationUtils.loadAnimation( SecondActivity.this, R.anim.grow_spin );
animation.setAnimationListener( new AnimationListener()
{
@Override
public void onAnimationStart( Animation animation ) {}
@Override
public void onAnimationRepeat( Animation animation ) {}
@Override
public void onAnimationEnd( Animation animation )
{
button.setVisibility( View.INVISIBLE );
goBack();
}
} );
button.startAnimation( animation );
}
});
}
@Override
protected void onResume()
{
findViewById( R.id.BackButton ).setVisibility( View.VISIBLE );
super.onResume();
}
private void goBack()
{
finish();
overridePendingTransition( R.anim.slide_in_right, R.anim.slide_out_right );
}
@Override
public boolean onKeyUp( int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
goBack();
return true;
}
return super.onKeyUp( keyCode, event );
}
If you have followed the previous articles in this series on animations, then this should all make sense. One thing worth pointing out is that I only want to apply the animation when the “Back” button is pressed, and not when the user hits the “Back” key on the device. If I wanted the same behaviour for both, then we would need to move the code to start and manage the animation in to the goBack() method.
If we try this, we can see that the grows quite large before suddenly disappearing as the transition between activities starts (because we set it to be invisible when the animation ends). What we’re going to do next is apply an alpha animation to run concurrently with the scale, to gradually fade the button. In res/anim/grow_spin.xml:
We have added the alpha animation (lines 6-8) which will animate from opaque to transparent (line 6), starting half a second after the entire animation starts (line 7), and lasting half a second (line 8), so it start half a second after the scale, and they will finish at the same time.
Finally let’s add a rotation, just so that we can see a rotation in action. In res/anim/grow_spin.xml:
We’ve added the rotate element (lines 9-11) which will rotate the button through 180 degrees (line 9), pivoting around the centre point of the button (line 10), taking half a second. Because we do not specify any startOffset value, this will begin at the start of the animation as a whole. Also, it does not matter which order these appear in, they will be executed according to the startOffset and durations. So this animation will have the scale running for a second, with the rotate occurring during the first half second, and the alpha occurring during the second half second.
Try that to see it working. It’s not very pretty, but it show how easy it is to combine animations using an animation set.
As a final little thing, suppose we want to set an interpolator to add some dynamics to the rotation, we could specify an interpolator in res/anim/grow_spin.xml:
We have added an iterpolator at line 12, but if we try this, it does not appear to have worked. That is because by default the child elements in an animation set inherit a common interpolator from the parent animation set. We could apply the interpolator to the “set” element, but then that would apply the interpolator to all of the animations within the set, which isn’t what we want. However, there is something that we can do to apply an interpolator only to the rotation, and that’s to add an attribute to the “set” forcing it to use a different intrpolator for each child. By default they will inherit from the parent as before, but t enables us to override the interpolators individually:
We can see this on line 2. If we try this, it now behaves as we want.
I probably don’t need to point out that the animations used in the examples are designed to show the animations working, but the actual app that we have created is a bit of a mess because the animations serve no purpose beyond demonstrating animation techniques. These examples demonstrate how animations can be used, not how they should be used. Never use animation simply for the sake of it. Often while an animation is showing (particularly during transitions between activities) user input is blocked. If the animation takes a few seconds to complete, we are effectively preventing the user from using an app. While it may often be tempting to use a fancy transition, always remember that if it takes too long, the user will perceive your app as being “laggy” and unresponsive. Essentially, animations should not be so bold as to be noticed. While that may seem strange, the key to using animations effectively is to make an app seem dynamic and polished and if your animations are too bold, they will actually detract from that.
As ever, the final source for this article can be found here.
© 2011, Mark Allison. All rights reserved.
Copyright © 2011 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.