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

如何使用Java调整Android中ProgressBar的旋转速度

解决方案

你当前XML布局中android:indeterminate="false"为确定进度模式,该模式不会自动无限旋转,要实现无限循环效果请先将该属性改为true,或在Java代码中动态调用setIndeterminate(true)开启。
原生AppCompat圆形ProgressBar未提供公开API直接调整旋转速度,旋转动画封装在内部的IndeterminateDrawable中,可通过以下两种Java代码方案调整转速:传入的时长参数越大,旋转速度越慢。


方案1:反射修改原有动画时长(代码量少,兼容绝大多数场景)

直接拿到控件内部的旋转动画实例,修改动画时长即可生效,封装好的工具方法如下:

import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.animation.Animation;
import android.widget.ProgressBar;
import java.lang.reflect.Field;

public class ProgressBarSpeedUtils {
    /**
     * 调整无限循环ProgressBar的旋转速度
     * @param progressBar 目标控件实例
     * @param rotateDurationMs 旋转一圈的时长,单位毫秒,默认系统值约1500ms
     */
    public static void setRotateSpeed(ProgressBar progressBar, long rotateDurationMs) {
        progressBar.setIndeterminate(true);
        Drawable indeterminateDrawable = progressBar.getIndeterminateDrawable();
        if (indeterminateDrawable == null) return;

        try {
            // 拿到内层实际持有动画的Drawable对象
            Field innerDrawableField = indeterminateDrawable.getClass().getDeclaredField("mDrawable");
            innerDrawableField.setAccessible(true);
            Object innerDrawable = innerDrawableField.get(indeterminateDrawable);
            if (innerDrawable == null) return;

            // 兼容不同SDK版本的动画字段名
            Field animField;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                animField = innerDrawable.getClass().getDeclaredField("mAnimation");
            } else {
                animField = innerDrawable.getClass().getDeclaredField("mRotateAnimation");
            }
            animField.setAccessible(true);
            Animation rotateAnim = (Animation) animField.get(innerDrawable);

            if (rotateAnim != null) {
                rotateAnim.setDuration(rotateDurationMs);
                // 重置动画让新时长生效
                indeterminateDrawable.setVisible(false, false);
                indeterminateDrawable.setVisible(true, false);
                if (indeterminateDrawable instanceof Animatable) {
                    ((Animatable) indeterminateDrawable).start();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

调用方式

在页面初始化拿到ProgressBar实例后直接调用即可,比如设置为3秒转一圈(比默认速度慢一半):

ProgressBar progressBar = findViewById(R.id.progressBar);
// 数值越大旋转越慢,可根据需求调整
ProgressBarSpeedUtils.setRotateSpeed(progressBar, 3000);

方案2:自定义旋转Drawable(无反射,稳定性最高)

如果担心反射在个别版本存在兼容性问题,可以直接在Java代码中创建自定义旋转Drawable,自行控制动画时长后设置给ProgressBar,示例代码如下:

import android.animation.ObjectAnimator;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RotateDrawable;
import android.view.animation.LinearInterpolator;
import android.widget.ProgressBar;

// 拿到系统默认的ProgressBar圆形Drawable
ProgressBar progressBar = findViewById(R.id.progressBar);
Drawable defaultDrawable = progressBar.getIndeterminateDrawable();
RotateDrawable rotateDrawable = new RotateDrawable();
rotateDrawable.setDrawable(defaultDrawable);
// 设置从0到360度旋转
rotateDrawable.setFromDegrees(0f);
rotateDrawable.setToDegrees(360f);
rotateDrawable.setPivotX(0.5f);
rotateDrawable.setPivotY(0.5f);

// 给ProgressBar设置自定义Drawable
progressBar.setIndeterminateDrawable(rotateDrawable);
progressBar.setIndeterminate(true);

// 通过属性动画控制旋转,时长自定义
ObjectAnimator animator = ObjectAnimator.ofInt(rotateDrawable, "level", 0, 10000);
animator.setDuration(3000); // 3秒转一圈,数值越大越慢
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(ObjectAnimator.INFINITE);
animator.start();

参数参考

  • 系统默认旋转一圈时长约1500ms,对应常规速度
  • 传入3000ms时,旋转速度为默认的1/2
  • 传入4500ms时,旋转速度为默认的1/3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:42:15