在动画期间平滑地更改动画持续时间
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) {
}
});
我在更新变量 elapsedTime
和 sessionLengthInSec
的值时遇到问题。这意味着有时 (elapsedTime > sessionLengthInSec)
是正确的,但它不应该是正确的,并且 circle.clearAnimation()
发生了......所以确定它产生了跳跃!
当然,如果持续时间变化太大,跳跃仍然会发生,但这是正常的,因为速度会迅速增加。在我的代码中,情况并非如此,因为速度增加小于 200 毫秒,因此肉眼几乎看不到/
很抱歉,实际上这段代码工作得很好...
我有两件事。
第一个是循环缩放动画,执行一种永久放大/缩小。
第二件事是 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) {
}
});
我在更新变量 elapsedTime
和 sessionLengthInSec
的值时遇到问题。这意味着有时 (elapsedTime > sessionLengthInSec)
是正确的,但它不应该是正确的,并且 circle.clearAnimation()
发生了......所以确定它产生了跳跃!
当然,如果持续时间变化太大,跳跃仍然会发生,但这是正常的,因为速度会迅速增加。在我的代码中,情况并非如此,因为速度增加小于 200 毫秒,因此肉眼几乎看不到/
很抱歉,实际上这段代码工作得很好...