You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何暂停与恢复圆形ImageView的旋转动画?

实现圆形ImageView旋转/暂停切换(停在当前位置)

嘿,这个需求其实很常见,咱们分两种方案来实现,优先推荐更简洁的属性动画方案,如果你坚持要用原来的补间动画也给你补全方法~

方案一:用ObjectAnimator(属性动画,推荐)

属性动画比补间动画更灵活,原生支持暂停和恢复,而且直接操作View的属性,暂停时会精准停在当前旋转角度,完全符合你的需求。修改你的MainActivity代码如下:

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.view.animation.LinearInterpolator;

public class MainActivity extends AppCompatActivity {
    private ObjectAnimator rotateAnimator;
    private ImageView imageview;
    private Button button1;
    private boolean isRotating = false; // 标记当前是否正在旋转

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageview = findViewById(R.id.imageview);
        button1 = findViewById(R.id.button1);

        // 创建旋转属性动画:操作ImageView的rotation属性,从0到360度
        rotateAnimator = ObjectAnimator.ofFloat(imageview, "rotation", 0f, 360f);
        rotateAnimator.setDuration(10000); // 10秒转一圈
        rotateAnimator.setInterpolator(new LinearInterpolator()); // 匀速旋转
        rotateAnimator.setRepeatCount(ValueAnimator.INFINITE); // 无限循环
        rotateAnimator.setRepeatMode(ValueAnimator.RESTART); // 每次循环从0开始(这里因为是360度,其实和REVERSE效果一样)

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isRotating) {
                    // 当前正在旋转,点击暂停
                    rotateAnimator.pause();
                } else {
                    // 当前已暂停,点击恢复/启动
                    if (rotateAnimator.isPaused()) {
                        rotateAnimator.resume();
                    } else {
                        rotateAnimator.start();
                    }
                }
                // 切换状态标记
                isRotating = !isRotating;
            }
        });
    }
}

为什么推荐这个方案?

  • 不用写xml动画文件,代码内直接配置更灵活
  • 原生支持pause()和resume(),无需手动计算角度,逻辑极简
  • 属性动画直接修改View的rotation属性,状态更稳定,不会出现补间动画的绘制层偏移问题

方案二:基于你原有的补间动画xml实现

如果你不想放弃原来的xml动画配置,我们可以通过记录当前旋转角度,每次暂停后重新创建从当前角度开始的动画:

首先在MainActivity中添加几个状态变量:

import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {
    private Animation cd1;
    private ImageView imageview;
    private Button button1;
    private boolean isRotating = false;
    private float currentDegree = 0f; // 记录当前暂停时的角度
    private long startTime; // 记录动画开始的时间,用于计算当前进度

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageview = findViewById(R.id.imageview);
        button1 = findViewById(R.id.button1);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isRotating) {
                    // 暂停动画:先取消当前动画,计算并记录当前角度
                    cd1.cancel();
                    long elapsedTime = System.currentTimeMillis() - startTime;
                    float progress = (float) elapsedTime / cd1.getDuration();
                    // 计算当前旋转的总角度(因为是无限循环,取模360得到当前实际角度)
                    currentDegree = (360 * progress) % 360;
                    isRotating = false;
                } else {
                    // 启动/恢复旋转:从当前角度开始创建新的动画
                    cd1 = AnimationUtils.loadAnimation(MainActivity.this, R.anim.cd_player1);
                    RotateAnimation rotateAnim = (RotateAnimation) cd1;
                    // 设置动画的起始角度为当前记录的角度,结束角度为当前角度+360
                    rotateAnim.setFromDegrees(currentDegree);
                    rotateAnim.setToDegrees(currentDegree + 360);
                    // 记录动画开始时间,用于后续计算进度
                    startTime = System.currentTimeMillis();
                    imageview.startAnimation(cd1);
                    isRotating = true;
                }
            }
        });
    }
}

注意点:

  • 每次暂停后都要重新加载动画并修改起始/结束角度,逻辑比属性动画繁琐
  • 补间动画是作用在View的绘制层,并非真正修改View的属性,所以如果View有位移或其他操作,可能会出现视觉偏移问题

内容的提问来源于stack exchange,提问作者Binh Cao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:05:17