I have an infinite translate animation applied to an ImageView
:
Animation animation = new TranslateAnimation(0, 0, -500, 500);
animation.setDuration(4000);
animation.setFillAfter(false);
myimage.startAnimation(animation);
animation.setRepeatCount(Animation.INFINITE);
What I have noticed is that the translation process is slower when the image is near the starting and ending point compared to when its near half the distance (middle point).
I guess the velocity for translate animations on android is not uniform.
How do I make the velocity uniform throughout the process ?
I did some source-diving to investigate this. First, note that if a linear interpolator is used to provide interpolatedTime
values to the applyTransformation
method of TranslateAnimation
, the resulting translation will have constant velocity (because the offsets dx
and dy
are linear functions of interpolatedTime
(lines 149-160)):
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float dx = mFromXDelta;
float dy = mFromYDelta;
if (mFromXDelta != mToXDelta) {
dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
}
if (mFromYDelta != mToYDelta) {
dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
}
t.getMatrix().setTranslate(dx, dy);
}
applyTransformation
is called by the getTransformation
method of the base Animation
class (lines 869-870):
...
final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
applyTransformation(interpolatedTime, outTransformation);
...
According to the documentation for the setInterpolator
method (lines 382-392), mInterpolator
should default to a linear interpolator:
/**
* Sets the acceleration curve for this animation. Defaults to a linear
* interpolation.
*
* @param i The interpolator which defines the acceleration curve
* @attr ref android.R.styleable#Animation_interpolator
*/
public void setInterpolator(Interpolator i) {
mInterpolator = i;
}
However, this seems to be false: both constructors in the Animation
class call the ensureInterpolator
method (lines 803-811):
/**
* Gurantees that this animation has an interpolator. Will use
* a AccelerateDecelerateInterpolator is nothing else was specified.
*/
protected void ensureInterpolator() {
if (mInterpolator == null) {
mInterpolator = new AccelerateDecelerateInterpolator();
}
}
which suggests that the default interpolator is an AccelerateDecelerateInterpolator
. This explains the behavior you describe in your question.
To actually answer your question, then, it would appear that you should amend your code as follows:
Animation animation = new TranslateAnimation(0, 0, -500, 500);
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(4000);
animation.setFillAfter(false);
myimage.startAnimation(animation);
animation.setRepeatCount(Animation.INFINITE);
来源:https://stackoverflow.com/questions/28393551/how-to-achieve-uniform-velocity-throughout-a-translate-animation