2

I'd like to make simple animation in Android project. I've got an image in my activity:

<ImageView
        android:id="@+id/pointer_png"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitCenter"
        android:adjustViewBounds="true"
        android:layout_gravity="center"
        android:src="@drawable/pointer_400" />

And here is my onClick method in activity class:

public void onStartButtonClick(View view){
    AnimationSet animationSet = new AnimationSet(true);
    animationSet.setInterpolator(new LinearInterpolator());
    animationSet.setFillAfter(true);

    RotateAnimation anim = new RotateAnimation(0.0f, -45.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    anim.setDuration(4000);
    animationSet.addAnimation(anim);

    RotateAnimation anim2 = new RotateAnimation(0.0f, 90.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    anim2.setDuration(4000);
    animationSet.addAnimation(anim2);

    RotateAnimation anim3 = new RotateAnimation(0.0f, -135.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    anim3.setDuration(4000);
    animationSet.addAnimation(anim3);

    RotateAnimation anim4 = new RotateAnimation(0.0f, 180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    anim4.setDuration(4000);
    animationSet.addAnimation(anim4);

    final ImageView pointer = (ImageView) findViewById(R.id.pointer_png);
    pointer.startAnimation(animationSet);
}

Unfortunately, the effect is unexpected. I'd like to rotate image in this sequence:

  1. Rotate 180 degrees within 4 seconds.
  2. Rotate -135 degrees within next 4 seconds.
  3. Rotate 90 degrees within next 4 seconds.
  4. Rotate -45 degrees within last 4 seconds.

But with this code animation is definitely shorter than 16 seconds and it's composed of one part only - 90 degrees from 0 point and it's over. Probably AnimationSet checks all animations and counts last position in my sequence. I've tried to set AnimationSet(false) and add separate LinearInterpolator to each RotateAnimation but it doesn't work.

What should I do to make my animation longer and with all rotations separated (4 steps, 4 seconds for every step)?

maniek099
  • 319
  • 4
  • 19
  • Try adding a start offset to your other animations using `setStartOffset()`. – TR4Android Aug 15 '16 at 12:13
  • I've tried with offsets: 0, 4000, 8000 and 12000 but final effect is very strage and unexpected. I'm afraid that I need to set AnimationListener to each animation and override onAnimationEnd method and there start next animation. It will be ok for this sequence but what with more complicated animations? – maniek099 Aug 15 '16 at 12:53

1 Answers1

2

From my experience an AnimationSet does not always work as expected and can be a pain in the a**. I would try using ViewPropertyAnimator.

Here is an example on how to use it. You can either set a startDelay like this :

pointer.animate()
    .rotation(...)   // <- enter rotation values here
    .setStartDelay(4000)
    .setInterpolator(new LinearInterpolator())
    .setDuration(4000);

or set an AnimationListener and start the next Animation in onAnimationEnd() when the one before has finished.

Spontaneously, if I had to do this I'd write my own method, something like this (not tested) :

private void rotate(View v, float rotation, int startDelay) {
    v.animate()
     .rotation(rotation)  // or rotationBy(rotation) whichever suits you better
     .setStartDelay(startDelay)
     .setInterpolator(new LinearInterpolator())
     .setDuration(4000);
}

and then call it four times like this :

rotate(pointer, -45, 0);
rotate(pointer, 90, 4000);
rotate(pointer, -135, 8000);
rotate(pointer, 180, 12000);
A Honey Bustard
  • 3,433
  • 2
  • 22
  • 38
  • Hello sir, found this answer here a little useful, I'm stuck in the similar problem, can you maybe have a look at it: https://stackoverflow.com/questions/59253778/update-attributes-during-rotation-animation/59255476#59255476 – KayD Dec 09 '19 at 19:50