在动画期间平滑地更改动画持续时间

Smoothly change animation duration during animating

我有两件事。

第一个是循环缩放动画,执行一种永久放大/缩小。

第二件事是 TimerTask 设置每 20 秒一次缩放动画的持续时间。

问题是当 setDuration() 出现时,动画中有时会出现某种 "jump"。

首先我将这个 setDuration() 放在 TimerTask 中,然后我只是尝试在 TimerTask 中放置一个标志并更改 onAnimationEnd() 中的持续时间,它没有' 既不工作,同样的问题。在下面的代码中,我使用了这个标记技术。

万一还不够清楚,所有这一切的目标是 "infinite" 放大/缩小可绘制的圆圈,放大/缩小速度会随着时间的推移而降低。确实可以用,就是上面说的不流畅

有没有办法顺利做到这一点?

设置标志的TimeTask"changeDurationFlag"

private void setRegularRythmeDecrease() {

    final Handler handler = new Handler();
    Timer timer = new Timer();

    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            handler.post(new Runnable() {
                public void run() {
                    try {
                        if (elapsedTime > sessionLengthInSec) {
                            circle.clearAnimation();
                        }
                        zoomDuration = zoomDuration + (toDecreaseEveryUpdate / 2);
                        changeDurationFlag = true;


                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    };
    timer.schedule(task, 0, BREATH_RYTHME_UPDATE_INTERVAL_IN_SECONDS*1000);
}

我用来放大和缩小的ScaleAnimation

public Animation scaleAnimation(View v, float startScale, float endScale, long duration) {
    Animation anim = new ScaleAnimation(
            startScale, endScale,
            startScale, endScale,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f);
    anim.setFillAfter(true);
    anim.setDuration(duration);
    return anim;
}

设置时长的动画监听器

    zoomDuration = ZOOM_DURATION_START;
    animZoomIn = scaleAnimation(circle, 1f, ZOOM_FACTOR,zoomDuration);
    animZoomOut = scaleAnimation(circle, ZOOM_FACTOR, 1f,zoomDuration);
    animZoomIn.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            // If the flag is true (modified in the TimerTask) I set the Duration to decrease the speed
            // it's where the not smoothly thing happens
            if(changeDurationFlag) { 
                Log.d("beat ","Set breath to " + String.valueOf(zoomDuration * 2d));
                animZoomIn.setDuration(zoomDuration);
                animZoomOut.setDuration(zoomDuration);
                changeDurationFlag = false;
            }
            circle.startAnimation(animZoomOut);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });
    animZoomOut.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {

            circle.startAnimation(animZoomIn);

            currentDateTime = Calendar.getInstance().getTime();
            elapsedTime = currentDateTime.getTime() - startDateTime.getTime();

            long elapsedTimeInSeconds = TimeUnit.MILLISECONDS.toSeconds(elapsedTime);

            beatCount++;
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    });

我在更新变量 elapsedTimesessionLengthInSec 的值时遇到问题。这意味着有时 (elapsedTime > sessionLengthInSec) 是正确的,但它不应该是正确的,并且 circle.clearAnimation() 发生了......所以确定它产生了跳跃!

当然,如果持续时间变化太大,跳跃​​仍然会发生,但这是正常的,因为速度会迅速增加。在我的代码中,情况并非如此,因为速度增加小于 200 毫秒,因此肉眼几乎看不到/

很抱歉,实际上这段代码工作得很好...