How to make a smooth image rotation in Android?
Solution 1
You are right about AccelerateInterpolator; you should use LinearInterpolator instead.
You can use the built-in android.R.anim.linear_interpolator
from your animation XML file with android:interpolator="@android:anim/linear_interpolator"
.
Or you can create your own XML interpolation file in your project, e.g. name it res/anim/linear_interpolator.xml
:
<?xml version="1.0" encoding="utf-8"?>
<linearInterpolator xmlns:android="http://schemas.android.com/apk/res/android" />
And add to your animation XML:
android:interpolator="@anim/linear_interpolator"
Special Note: If your rotate animation is inside a set, setting the interpolator does not seem to work. Making the rotate the top element fixes it. (this will save your time.)
Solution 2
I had this problem as well, and tried to set the linear interpolator in xml without success. The solution that worked for me was to create the animation as a RotateAnimation in code.
RotateAnimation rotate = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(5000);
rotate.setInterpolator(new LinearInterpolator());
ImageView image= (ImageView) findViewById(R.id.imageView);
image.startAnimation(rotate);
Solution 3
This works fine
<?xml version="1.0" encoding="UTF-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1600"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="358" />
To reverse rotate:
<?xml version="1.0" encoding="UTF-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1600"
android:fromDegrees="358"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="0" />
Solution 4
Maybe, something like this will help:
Runnable runnable = new Runnable() {
@Override
public void run() {
imageView.animate().rotationBy(360).withEndAction(this).setDuration(3000).setInterpolator(new LinearInterpolator()).start();
}
};
imageView.animate().rotationBy(360).withEndAction(runnable).setDuration(3000).setInterpolator(new LinearInterpolator()).start();
By the way, you can rotate by more than 360 like:
imageView.animate().rotationBy(10000)...
Solution 5
Try using toDegrees="359"
since 360° and 0° are the same.
Related videos on Youtube
emmby
Author of Android Application Development for Dummies. Author of RoboGuice, as well as the OpenTable, TripIt, and Digg Android applications. bebop Mobile at Google http://about.me/michaelburton
Updated on November 27, 2021Comments
-
emmby over 2 years
I'm using a
RotateAnimation
to rotate an image that I'm using as a custom cyclical spinner in Android. Here's myrotate_indefinitely.xml
file, which I placed inres/anim/
:<?xml version="1.0" encoding="UTF-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:repeatCount="infinite" android:duration="1200" />
When I apply this to my
ImageView
usingAndroidUtils.loadAnimation()
, it works great!spinner.startAnimation( AnimationUtils.loadAnimation(activity, R.anim.rotate_indefinitely) );
The one problem is that the image rotation seems to pause at the top of every cycle.
In other words, the image rotates 360 degrees, pauses briefly, then rotates 360 degrees again, etc.
I suspect that the problem is that the animation is using a default interpolator like
android:iterpolator="@android:anim/accelerate_interpolator"
(AccelerateInterpolator
), but I don't know how to tell it not to interpolate the animation.How can I turn off interpolation (if that is indeed the problem) to make my animation cycle smoothly?
-
emmby over 14 yearsGreat theory. I'm pretty sure it's not that because the speedup/slowdown is quite smooth and deliberate looking. Just in case though I tried decreasing the degrees to 358 and there was no discernible change in behavior.
-
Kingpin about 13 yearsThis is because interpolator was spelled wrong (no "n"). You don't need to make your own
-
Adam Rabung over 12 yearsI've tried every interpolator available, including the linear, and i still get this little "hitch" at the beginning of every cycle.
-
shalafi almost 12 yearsIf your rotate animation is inside a set, setting the interpolator does not seem to work. Making the rotate the top element fixes it
-
RoundSparrow hilltx over 9 yearsFor reverse, just have repeatcount 2 and set android:repeatMode="reverse" - no need to have two different XML files.
-
agonist_ almost 8 yearsHey, what if you actually want to use accelerate_decelerate_interpolator without the small "pause" between every animations ?
-
XcodeNOOB over 7 yearsWorking perfect, is imageView.clearAnimation() will clean up the runnable as well ?
-
Abhijit Jagtap about 7 yearsIts working fine for start animation, but after start runnable its not clean up by imageView.clearAnimation(), i used in touch listener event
-
behelit about 7 yearswhy 358 and not 359 or 360?
-
abggcv almost 7 yearsWhere to add this file to in resources? Is animation a separate package for this?
-
Fonix almost 6 yearsif you want the animation to stay at the orientation at the end, add
rotate.setFillAfter(true);
-
Pants over 5 yearsCan't stop these runnables independently
-
Vitaly Zinchenko over 5 years@Pants you can call withEndAction(this) on some condition. If the condition is false, withEndAction(this) won't be called, and animation should stop
-
Rishabh Saxena over 5 yearswhere is you "animation" variable declaration ?
-
ahmednabil88 about 5 yearsif you want the animation to stay permanently with no end, add
rotate.setRepeatCount(Animation.INFINITE);
-
borchvm about 4 yearsWhile this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained.
-
smrf over 3 yearsif you want the object to rotate infinitely, you need to set the degree from 180 to 360. also, setFillAfter as mention by Fonix is needed
-
serif almost 2 yearscomes alive with alpha