AnimatorSet 在顺序播放时停止
AnimatorSet stopping when playing sequentially
我有一些代码可以创建一个名为路径的点列表。
这是一个示例列表:[[1, 3], [2, 3], [2, 4]]
这是我编写的用于按顺序移动到这些点的动画代码:
ArrayList<Animator> movements = new ArrayList<>();
int prevY = start[1];
int prevX = start[0];
for (int[] square : path) {
ObjectAnimator motion = new ObjectAnimator();
float[] coord = screenFromGrid(square[0], square[1], gridSizeY);
long speed = (long) (6000.0 / this.displayMetrics.widthPixels);
speed = (long) (speed * getSquareSize(gridSizeY));
if (square[0] != prevX) {
motion = ObjectAnimator.ofFloat(this.sprite1, "x", coord[0]);
motion.setInterpolator(new LinearInterpolator());
motion.setDuration(speed);
movements.add(motion);
prevX = square[0];
} else if (square[1] != prevY) {
motion = ObjectAnimator.ofFloat(this.sprite1, "y", coord[1]);
motion.setInterpolator(new LinearInterpolator());
motion.setDuration(speed);
movements.add(motion);
prevY = square[1];
}
}
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playSequentially(movements);
animatorSet.start();
问题是动画在中间完全停止,没有抛出任何错误。
我检查了调试器,它说所有动画都已正确存储。
有人知道为什么会这样吗?
根据我的经验,我只知道 AnimatorSet 有问题,并不总是按预期工作,我也遇到过问题,幸运的是找到了另一种更好的方法:
ViewPropertyAnimator 是一种使用简短代码为视图设置动画的好方法。您可以编写自己的方法,您可以根据需要修改和重用该方法,例如:
private void customAnimation(View view, float toX, float toY, int duration, boolean loop) {
view.animate()
.translationX(toX)
.translationY(toY)
.setDuration(duration)
.setInterpolator(new LinearInterpolator())
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if(loop) {
customAnimation(..., false);
}
}
});
侦听器等待第一个动画完成,因此您可以在那里调用下一个动画。为了按顺序播放而不永远循环播放,我在参数中添加了一个布尔值,如果为真,则只执行下一个动画。
这也会将您的其余代码缩短为如下所示:
int prevY = start[1];
int prevX = start[0];
for (int[] square : path) {
float[] coord = screenFromGrid(square[0], square[1], gridSizeY);
long speed = (long) (6000.0 / this.displayMetrics.widthPixels);
speed = (long) (speed * getSquareSize(gridSizeY));
if (square[0] != prevX) {
customAnimation(this.sprite1, coord[0], 0, speed, true);
prevX = square[0];
} else if (square[1] != prevY) {
customAnimation(this.sprite1, 0, coord[1], speed, true);
prevY = square[1];
}
}
一定要检查 docs for all available methods, maybe .translationXBy(float byX) is more suited in your case than .translationX(float toX)
我有一些代码可以创建一个名为路径的点列表。
这是一个示例列表:[[1, 3], [2, 3], [2, 4]]
这是我编写的用于按顺序移动到这些点的动画代码:
ArrayList<Animator> movements = new ArrayList<>();
int prevY = start[1];
int prevX = start[0];
for (int[] square : path) {
ObjectAnimator motion = new ObjectAnimator();
float[] coord = screenFromGrid(square[0], square[1], gridSizeY);
long speed = (long) (6000.0 / this.displayMetrics.widthPixels);
speed = (long) (speed * getSquareSize(gridSizeY));
if (square[0] != prevX) {
motion = ObjectAnimator.ofFloat(this.sprite1, "x", coord[0]);
motion.setInterpolator(new LinearInterpolator());
motion.setDuration(speed);
movements.add(motion);
prevX = square[0];
} else if (square[1] != prevY) {
motion = ObjectAnimator.ofFloat(this.sprite1, "y", coord[1]);
motion.setInterpolator(new LinearInterpolator());
motion.setDuration(speed);
movements.add(motion);
prevY = square[1];
}
}
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playSequentially(movements);
animatorSet.start();
问题是动画在中间完全停止,没有抛出任何错误。
我检查了调试器,它说所有动画都已正确存储。
有人知道为什么会这样吗?
根据我的经验,我只知道 AnimatorSet 有问题,并不总是按预期工作,我也遇到过问题,幸运的是找到了另一种更好的方法: ViewPropertyAnimator 是一种使用简短代码为视图设置动画的好方法。您可以编写自己的方法,您可以根据需要修改和重用该方法,例如:
private void customAnimation(View view, float toX, float toY, int duration, boolean loop) {
view.animate()
.translationX(toX)
.translationY(toY)
.setDuration(duration)
.setInterpolator(new LinearInterpolator())
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if(loop) {
customAnimation(..., false);
}
}
});
侦听器等待第一个动画完成,因此您可以在那里调用下一个动画。为了按顺序播放而不永远循环播放,我在参数中添加了一个布尔值,如果为真,则只执行下一个动画。
这也会将您的其余代码缩短为如下所示:
int prevY = start[1];
int prevX = start[0];
for (int[] square : path) {
float[] coord = screenFromGrid(square[0], square[1], gridSizeY);
long speed = (long) (6000.0 / this.displayMetrics.widthPixels);
speed = (long) (speed * getSquareSize(gridSizeY));
if (square[0] != prevX) {
customAnimation(this.sprite1, coord[0], 0, speed, true);
prevX = square[0];
} else if (square[1] != prevY) {
customAnimation(this.sprite1, 0, coord[1], speed, true);
prevY = square[1];
}
}
一定要检查 docs for all available methods, maybe .translationXBy(float byX) is more suited in your case than .translationX(float toX)