Android Object Animator executes longer than the duration

1.8k views Asked by At

I've an ObjectAnimator to rotate an image every 200 milliseconds until it reaches from 0 to 360 angle. Everything works fine, expect the duration it takes. For one cycle, the animation is running 20 to 30 milliseconds (varies on devices) more, which is 220 milliseconds instead of 200 milliseconds.

Requirement is to move an image from 360 to 0 angle. in 10seconds.

The Image initial angle is set as 360 and should reach 0 angle in 10 seconds with image moving only every 200 milliseconds.

So, i have a button when clicked , will call the rotate method with the from and to angle as

      // initial angle is 360 and should reach 0 in 10 seconds with image moving only every 200 milliseconds.
  rotate(360 , 360 - 7.2f); // from 360 to 352.8
      // to run 10000 milliseconds with 200 milliseconds interval it would take 50 cycle for animation to run
     // so the angle to move each cycle will be 360/50 = 7.2

Rotate method is called recursively , to move to next angle.

private void rotate(float fromAngle , final float toAngle){
    ImageView imageView = (ImageView) findViewById(R.id.rotate_image_view);

    ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "rotation", fromAngle, toAngle);
    objectAnimator.setDuration(200);

    objectAnimator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            Log.d(TAG , "End time " + System.currentTimeMillis());
            if(toAngle > 0) {
                float moveAngleTo = toAngle - 7.2f; // next angle position
                // round next angle to 0 if goes to negative
                if(moveAngleTo < 0){
                    moveAngleTo = 0;
                }
                rotate(toAngle , moveAngleTo);
            }
        }

        @Override
        public void onAnimationStart(Animator animation) {
            Log.d(TAG , "Start time " + System.currentTimeMillis());
        }
    });
    objectAnimator.start();
}

Expected is the total duration should be 10 seconds, but each cycle runs more than 200 milliseconds ,which adds to the total above 11 seconds (ie, 20 x 50 = 1000 milliseconds).

1

There are 1 answers

0
Rakesh On

Try following code:

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mView, "rotation", fromAngle, toAngle);

    objectAnimator.setDuration(200);
    objectAnimator.setRepeatCount(ObjectAnimator.INFINITE);
    objectAnimator.setRepeatMode(ObjectAnimator.RESTART);
    objectAnimator.setInterpolator(new AccelerateInterpolator());

    objectAnimator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            LogUtil.d(TAG , "End time " + System.currentTimeMillis());
        }

        @Override
        public void onAnimationStart(Animator animation) {
            LogUtil.d(TAG , "Start time " + System.currentTimeMillis());
        }
        @Override
        public void onAnimationRepeat(Animator animation) {
            animation.setInterpolator(new LinearInterpolator());
        }
    });