Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android : How to choose the rotation direction of a RotateAnimation?

I am currently working on an application in which one I would like to indicate a path with an arrow (it works like a compass).

In order to move the arrow to the good direction, I use the RotateAnimation class. It works very well but when the initial degrees position is far from the final degrees position, the rotation does not choose the faster way.

In this video, you can see the behavior : https://youtu.be/vypZni_1s3I

Here the code that is executed when the user click the button "02" :

RotateAnimation rotateAnimation = new RotateAnimation(355f, 8f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateAnimation.setDuration(3000);
rotateAnimation.setFillAfter(true);
test.startAnimation(rotateAnimation);

Here the code that is executed when the user click the button "03" :

RotateAnimation rotateAnimation = new RotateAnimation(8f, 350f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateAnimation.setDuration(3000);
rotateAnimation.setFillAfter(true);
test.startAnimation(rotateAnimation);

As you can see in the video, the rotation does not choose the faster way. In the first animation, the faster way is to have a clockwise rotation (but the system chooses ann anticlockwise rotation) and in the second animation, the faster way is to have an anticlockwise rotation (but the system chooses a clockwise rotation).

Is there a solution or a trick to force the system to choose the faster way in order to rotate from a point A to a point B ?

like image 513
rolandl Avatar asked Dec 10 '22 15:12

rolandl


1 Answers

The RotationAnimation object will turn clockwise if the parameter toDegrees is greater than the parameter fromDegrees. You have to handle yourself the fact that actually, yo do not want to go from 355f to 8f, but from 355f to 368f (which is 360 degrees plus 8 degrees).

So here you would change your two pieces of code as follows :

RotateAnimation rotateAnimation = new RotateAnimation(355f, 368f, 
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateAnimation.setDuration(3000);
rotateAnimation.setFillAfter(true);
test.startAnimation(rotateAnimation);

and

RotateAnimation rotateAnimation = new RotateAnimation(368f, 350f, 
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setInterpolator(new LinearInterpolator());
rotateAnimation.setDuration(3000);
rotateAnimation.setFillAfter(true);
test.startAnimation(rotateAnimation);

But I would suggest you, if you are willing to create an app using API 14+ to use the animate() method of View like this :

test.animate()
  .rotationBy(13f)
  .setDuration(3000)
  .setInterpolator(new LinearInterpolator())
  .start();

The rotationBy(offset) method will rotate your view - with a central pivot - by offset degrees, clockwise if offset is positive, anticlockwise otherwise.

like image 72
David Fournier Avatar answered May 01 '23 07:05

David Fournier