问题
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 ?
回答1:
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