重复几次后,Android RotateAnimation会变慢

重复几次后,Android RotateAnimation会变慢,android,animation,rotation,lag,Android,Animation,Rotation,Lag,我正在尝试制作一个节拍器,它的指针像倒立的钟摆一样移动。 我已经尝试过android的旋转动画来实现这一点,但在运行了几次之后,它似乎慢了下来。 我已经尝试了LinearIntrolator和自定义插值器TronomeInterpolator 以下代码取自,谢谢IHaN JiTHiN RotateAnimation needleDeflection = new RotateAnimation( this.previousAngle, this.currentAngle,

我正在尝试制作一个节拍器,它的指针像倒立的钟摆一样移动。 我已经尝试过android的旋转动画来实现这一点,但在运行了几次之后,它似乎慢了下来。 我已经尝试了LinearIntrolator和自定义插值器TronomeInterpolator

以下代码取自,谢谢IHaN JiTHiN

RotateAnimation needleDeflection = new RotateAnimation(
            this.previousAngle, this.currentAngle, this.pivotX, this.pivotY) {
        protected void applyTransformation(float interpolatedTime,
                Transformation t) {
            currentDegrees = previousAngle + (currentAngle - previousAngle)
                    * interpolatedTime;
            currentValue = (((currentDegrees - minAngle) * (maxValue - minValue)) / (maxAngle - minAngle))
                    + minValue;
            if (NDL != null)
                NDL.onDeflect(currentDegrees, currentValue);
            super.applyTransformation(interpolatedTime, t);
        }

    };

    needleDeflection.setAnimationListener(new AnimationListener() {
        @Override
        public void onAnimationStart(Animation arg0) {
        }

        @Override
        public void onAnimationRepeat(Animation arg0) {
        }

        @Override
        public void onAnimationEnd(Animation arg0) {
            previousAngle = currentAngle;
        }
    });
    needleDeflection.setDuration(this.deflectTime);
    needleDeflection.setInterpolator(new MetronomeInterpolator());
    needleDeflection.setFillBefore(true);
    needleDeflection.setFillAfter(false);
    needleDeflection.setStartOffset(0);
    needleDeflection.setRepeatMode(Animation.RESTART);
    needleDeflection.setRepeatCount(Animation.INFINITE);
    this.gaugeNeedle.startAnimation(needleDeflection);
    this.gaugeNeedle.refreshDrawableState();
动画将无限次重新启动

public class MetronomeInterpolator implements Interpolator {
private double p=0.5;

@Override
public float getInterpolation(float t) {
    // a: amplitude, p: period/2
    //https://stackoverflow.com/questions/1073606/is-there-a-one-line-function-that-generates-a-triangle-wave
    double a=1;
    return (float)((a/p) * (p - Math.abs(t % (2*p) - p)));
}
}
节拍器正形成一个三角波。该公式取自,谢谢Lightsider

除了计时之外,整个动画都非常完美。动画第一次正确开始和结束。但是,在重复几次之后,动画似乎比应该的慢。i、 e.背景中播放滴答声,经验证准确,但旋转动画在重复几次后滞后


原因之一是某些代码在重复之前正在运行。你可以建议一种方法来做动画使用任何解决方案,可以在android中使用,使一个准确的钟摆?多谢各位

我通过在动画监听器中添加代码解决了这个问题。 我记录了动画开始时的开始时间。 重复时,我计算动画应该使用的预期持续时间。 将其与动画使用的时间进行比较。 如果动画使用的时间超过预期,请缩短动画持续时间。 如果动画使用的时间少于预期时间,则重置为定义的持续时间

    needleDeflection.setAnimationListener(new AnimationListener() {
        @Override
        public void onAnimationStart(Animation arg0) {
            long startTime=AnimationUtils.currentAnimationTimeMillis();
            GaugeView.this.animateRepeatedTimes=0;
            GaugeView.this.animateStartTime = startTime;
        }

        @Override
        public void onAnimationRepeat(Animation arg0) {
            //duration of the animation * number of runs of animation + (long)starttime
            long expectedEndTime = GaugeView.this.deflectTime* ++GaugeView.this.animateRepeatedTimes + GaugeView.this.animateStartTime;
            long repeatTime=AnimationUtils.currentAnimationTimeMillis();
            long timeExcessUsed = repeatTime - expectedEndTime;
            if(timeExcessUsed>0){
                //reduce the animation duration
                arg0.setDuration(GaugeView.this.deflectTime-timeExcessUsed);
            }else{
                //reset the animation duration to normal
                arg0.setDuration(GaugeView.this.deflectTime);
            }
        }

        @Override
        public void onAnimationEnd(Animation arg0) {
            previousAngle = currentAngle;
        }
    });