Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Applying transformation after animating an object on android

I'm trying to animate a ball image coming into the screen, shifting position within the screen and go back out of the screen. I want to do this in form of 3 animations; ball_in, ball_shift and ball_out, as well as being able to decide when to go from one animation to the other.

This is the code I got so far;

Main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<ImageView android:id="@+id/ballImage" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" 
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_margin="5px"
android:src="@drawable/red_ball"
/>


</RelativeLayout>

Main activity

public class AnimationTest extends Activity
{
    AnimationDrawable ballAnimation;

    public void onCreate(Bundle savedInstanceState)
    {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);

      final ImageView ballImage = (ImageView) findViewById(R.id.ballImage);

      final Animation ballOutAnimation = AnimationUtils.loadAnimation(this, R.anim.ball_out);

      final Animation ballShiftAnimation = AnimationUtils.loadAnimation(this, R.anim.ball_shift);
      ballShiftAnimation.setAnimationListener( new AnimationListener()
        {

            @Override
            public void onAnimationEnd(
                    Animation animation) {

                ballImage.startAnimation(ballOutAnimation);
            }

            @Override
            public void onAnimationRepeat(
                    Animation animation) {}

            @Override
            public void onAnimationStart(
                    Animation animation) {}

        });

      final Animation ballInAnimation = AnimationUtils.loadAnimation(this, R.anim.ball_in);
      ballInAnimation.setAnimationListener( new AnimationListener()
        {

            @Override
            public void onAnimationEnd(
                    Animation animation) {
                ballImage.startAnimation(ballShiftAnimation);
            }

            @Override
            public void onAnimationRepeat(
                    Animation animation) {}

            @Override
            public void onAnimationStart(
                    Animation animation) {}

        });

      ballImage.startAnimation(ballInAnimation);

    }

}

ball_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<translate
    android:fromXDelta="150"
    android:toXDelta="0"

    android:fromYDelta="0"
    android:toYDelta="0"

    android:duration="2000"
    android:startOffset="0"
    />

<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">        
    <translate
        android:fromXDelta="0"
        android:toXDelta="0"

        android:fromYDelta="-150"
        android:toYDelta="0"

        android:duration="1500"
        android:startOffset="500"
        />

</set>

</set>

ball_shift.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<translate
    android:fromXDelta="0"
    android:toXDelta="130"

    android:fromYDelta="0"
    android:toYDelta="220"

    android:duration="2000"
    android:startOffset="0"

    android:fillAfter="true"
    />

<scale
    android:fromXScale="1.0" 
    android:toXScale="0.623"

    android:fromYScale="1.0" 
    android:toYScale="0.623" 

    android:duration="2000"
    android:startOffset="0"

    android:fillAfter="true"
    />

</set>

ball_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">        
<scale
    android:fromXScale="0.623" 
    android:toXScale="0.623"

    android:fromYScale="0.623" 
    android:toYScale="0.623" 
    />

<translate
    android:fromXDelta="130"
    android:toXDelta="330"

    android:duration="2000"
    android:startOffset="0"
    />
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator">        
    <translate
        android:fromYDelta="220"
        android:toYDelta="370"

        android:duration="1900"
        android:startOffset="100"
        />

</set>

</set>

I originally had everything in one long animation, but wanted to split the animations up to be able to stop and continue at a given time in the code. Doing so, I realized that the position of the image was reset back to the starting position when the animation was finished and this of course gave me weird results when splitting up the animations.

I tried using fillAfter/fillBefore, which is described as applying transformations after/before the animation process, but they doesnt seem to do anything to the image. It still resets back to the starter position.

Any help or suggestions on how to do this is appriciated. Thanks.

like image 248
Avilan Avatar asked Oct 25 '25 00:10

Avilan


1 Answers

You should use an AnimationSet for concatenating animation programatically in android. It should look something like this

AnimationSet anim = new AnimationSet(false);

final Animation ballInAnimation = AnimationUtils.loadAnimation(this,
            R.anim.ball_in);
ballInAnimation.setFillBefore(true);

final Animation ballShiftAnimation = AnimationUtils.loadAnimation(this,R.anim.ball_shift);
ballShiftAnimation.setStartOffset(ballInAnimation.getDuration());

final Animation ballOutAnimation = AnimationUtils.loadAnimation(this,R.anim.ball_out);
ballOutAnimation.setStartOffset(ballInAnimation.getDuration()+ ballShiftAnimation.getDuration());

anim.addAnimation(ballInAnimation);
anim.addAnimation(ballShiftAnimation);
anim.addAnimation(ballOutAnimation);
anim.setFillAfter(true);

ballImage.startAnimation(anim);

This should work given your TweenAnimations defined in the XML are properly connected. Notice that this will only work VISUALLY, if you need the view to be clickable, you should use ValueAnimator instead of the Animation

like image 181
apenasVB Avatar answered Oct 26 '25 15:10

apenasVB