views:

406

answers:

0

Hello everyone,

I spent so much time looking into Android animation tween that I wanted to share this knowledge (and maybe others can provide feedback and improvements).

I wanted to draw an animation for Android where the following sequence of animation would happen.

  1. Star would move to the center from outside of the screen.
  2. The star would rotate as it is moving and reduce its speed when reaching the center.
  3. The star would start to increase speed and start rotating and move out of the screen.

The biggest problem with this was the second part of the animation, where the star must rotate and move from center to right. However, due to the offset x and y being originated to the beginning of the animation, that it would make a wide circular rotation.

So taking time to figure this out, I eventually came up with the following solution. It is a messy solution, so I would appreciate if anyone had a better idea on how I can approach this.

First, we need to create the animation file in xml, and we will call it anim_1 and anim_2, respectively.

Here is the code for the xml.

<?xml version="1.0" encoding="UTF-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillBefore="true"
android:fillAfter="true" >
<rotate
android:pivotX="50%" 
android:pivotY="50%"
android:fromDegrees="0" 
android:toDegrees="360"
android:toYScale="0.0" 
android:duration="3000"
android:fillBefore="true"
android:fillAfter="true" 
/>
<translate 
android:interpolator="@android:anim/accelerate_interpolator"
android:fromXDelta="-100"
android:toXDelta="100"
android:fromYDelta="100"
android:toYDelta="100"
android:duration="3000"
android:fillBefore="true"
android:fillAfter="true" 
/>
</set>

What the above code is referring is to have a rotating animation (along it's center as a pivot) that moves from left (x=-100, y=100) and slow down as it reaches the center of the screen (x=100, y=100) within the time frame of 3 seconds.

The anim_2 would have the same format, except the fromXDelta would be 100, toXDelta would be 300, so that the animation can start where it finished.

Next we will have the main code that will set these animations.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ImageView animWindow = (ImageView)findViewById(R.id.image_view);
    Animation anim_1 = AnimationUtils.loadAnimation(this, R.anim.anim_1);
    animWindow.startAnimation(anim_1);
    animWindow.getAnimation().setAnimationListener(new AnimationListener()
    {
        public void onAnimationEnd(Animation animation)
        {
            startSecondAnimation();
        }

        public void onAnimationStart(Animation animation){}

        public void onAnimationRepeat(Animation animation){}
    });
}

public void startSecondAnimation()
{
    Animation anim_2 = AnimationUtils.loadAnimation(this, R.anim.anim_2);
    ImageView animWindow = (ImageView)findViewById(R.id.image_view);
    animWindow.startAnimation(anim_2);
}

I wish there was a cleaner way to handle the animation, but because of the offset not being centered on the image, the ImageView had to be re-initialized. Hope this helps.