How to achieve uniform velocity throughout a Translate Animation?

被刻印的时光 ゝ 提交于 2019-12-19 10:26:18

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!