如何按顺序播放AnimatorSet列表?实现ImageView绕圆旋转动画
解决ImageView绕圆形旋转并支持重复执行不同参数动画的问题
你的代码当前的问题在于循环里每次创建AnimatorSet并立即启动,这会导致所有动画瞬间同时执行,而不是按顺序完成绕圈动作,自然也没法重复或者调整参数重新执行。咱们换一种更高效且可控的方式来实现这个动画——用ValueAnimator来驱动整个圆形路径的计算,这样不仅能流畅完成绕圈,还能轻松修改参数重复执行。
优化后的完整实现代码
public void startCircleAnimation(ImageView targetView, ImageView centerView, long duration, int repeatCount, int repeatMode) { // 计算圆形路径的中心和半径 int radius = centerView.getHeight() * 30 / 70; int centerX = centerView.getLeft() + radius; int centerY = centerView.getTop() + radius; // 创建从0到360度的数值动画,用来驱动角度变化 ValueAnimator circleAnimator = ValueAnimator.ofFloat(0f, 360f); circleAnimator.setDuration(duration); // 设置重复次数和模式:比如ValueAnimator.INFINITE无限重复,或者指定次数;RESTART从头来/REVERSE反向 circleAnimator.setRepeatCount(repeatCount); circleAnimator.setRepeatMode(repeatMode); // 监听动画每一帧的更新,计算当前位置和旋转角度 circleAnimator.addUpdateListener(animation -> { float currentAngle = (float) animation.getAnimatedValue(); // 将角度转为弧度(Math.cos/sin需要弧度值) double radian = Math.toRadians(currentAngle); // 计算目标View当前的x、y坐标 float targetX = (float) (centerX + radius * Math.cos(radian)); float targetY = (float) (centerY + radius * Math.sin(radian)); // 更新目标View的位置和旋转角度 targetView.setX(targetX); targetView.setY(targetY); targetView.setRotation(currentAngle); }); // 启动动画 circleAnimator.start(); }
如何使用这个方法
你可以随时调用这个方法,传入不同的参数来执行不同的绕圈动画:
// 示例1:让carView绕worldView以5秒一圈的速度无限重复旋转 ImageView worldView = findViewById(R.id.imageView); ImageView carView = findViewById(R.id.carImageView); startCircleAnimation(carView, worldView, 5000, ValueAnimator.INFINITE, ValueAnimator.RESTART); // 示例2:修改参数,以3秒一圈的速度重复2次,然后反向旋转 startCircleAnimation(carView, worldView, 3000, 2, ValueAnimator.REVERSE);
为什么你的原有代码不行?
- 动画执行逻辑错误:循环里每次创建AnimatorSet并立即
start(),所有动画会同时触发,导致View直接跳到最后一个坐标,看不到绕圈过程。 - 角度计算精度丢失:你把弧度值转成了
int,这会导致角度计算严重失真,路径变成多边形而不是圆形。 - 无法重复控制:没有统一的动画容器来管理整个序列,自然没法调整参数重复执行。
额外提示
- 如果需要让View的旋转方向和移动方向一致(比如车头始终朝向运动方向),可以把
setRotation(currentAngle)改成setRotation(currentAngle - 90)(根据你的View初始方向调整偏移量)。 - 可以在动画开始前先把targetView的初始位置设置到圆形路径的起点,避免突兀的跳转。
内容的提问来源于stack exchange,提问作者Julien Trijean
相关产品推荐
相关产品推荐

