How to achieve uniform velocity throughout a Translate Animation?

后端 未结 1 1502
情歌与酒
情歌与酒 2021-01-14 05:40

I have an infinite translate animation applied to an ImageView:

Animation animation = new TranslateAnimation(0, 0, -500, 500);
animation.setDura         


        
相关标签:
1条回答
  • 2021-01-14 06:29

    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);
    
    0 讨论(0)
提交回复
热议问题