You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android自定义ProgressBar及自定义不确定进度条的实现与使用方法咨询

Hey there! Let's walk through how to build custom ProgressBars in Android, covering both determinate (the one with a clear progress percentage) and indeterminate (the spinning/animated one for unknown wait times) versions. I'll include practical code snippets you can copy-paste and tweak for your app.

1. 自定义确定型ProgressBar

Determinate progress bars are perfect for scenarios like file downloads, uploads, or tasks where you know exactly how much progress has been made. Here's how to customize yours:

Step 1: Create a Custom Progress Drawable

First, make a new drawable file in res/drawable/ (name it custom_progress_bar.xml). We'll use a layer-list to stack the background track and the progress fill:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Background track -->
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="8dp" />
            <solid android:color="#E0E0E0" />
        </shape>
    </item>
    <!-- Progress fill -->
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="8dp" />
                <solid android:color="#2196F3" /> <!-- Use ?attr/colorPrimary for theme consistency -->
            </shape>
        </clip>
    </item>
</layer-list>

Step 2: Use the Custom ProgressBar in Your Layout

Add the ProgressBar to your layout file, and point its progressDrawable to the drawable we just created. Make sure to use the horizontal style since we're making a determinate bar:

<ProgressBar
    android:id="@+id/customProgressBar"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:layout_width="match_parent"
    android:layout_height="8dp"
    android:layout_margin="16dp"
    android:progressDrawable="@drawable/custom_progress_bar"
    android:max="100" />

Step 3: Control Progress in Code

In your Activity/Fragment, you can update the progress programmatically. For example, simulating a download with a coroutine:

// In Kotlin
val progressBar = findViewById<ProgressBar>(R.id.customProgressBar)

// Simulate progress update
lifecycleScope.launch {
    repeat(100) { progress ->
        delay(50) // Simulate work being done
        progressBar.setProgress(progress + 1, true) // The second parameter enables smooth animation
    }
}
2. 创建自定义不确定型进度条

Indeterminate progress bars are for when you don't know how long a task will take—like loading data from a server. You can customize their animation or appearance in a few ways:

Method 1: Custom Rotating Drawable

Create a rotating shape drawable for a simple, customizable spinner. Make res/drawable/custom_indeterminate_progress.xml:

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:duration="1000"> <!-- Adjust speed by changing duration -->

    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thicknessRatio="8"
        android:useLevel="false">

        <gradient
            android:type="sweep"
            android:startColor="#2196F3"
            android:centerColor="#BB2196F3"
            android:endColor="#002196F3"
            android:angle="0" />
    </shape>
</rotate>

Then use it in your layout:

<ProgressBar
    android:id="@+id/customIndeterminateBar"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:indeterminateDrawable="@drawable/custom_indeterminate_progress" />

Method 2: Custom Property Animation

If you want a more unique animation (like pulsing or scaling), you can use property animations directly in code. For example, a pulsing spinner:

// In Kotlin
val customSpinner = findViewById<View>(R.id.customSpinnerView) // Use a simple View as your spinner

// Create scale animation
val scaleAnimator = ObjectAnimator.ofPropertyValuesHolder(
    customSpinner,
    PropertyValuesHolder.ofFloat(View.SCALE_X, 0.8f, 1.2f),
    PropertyValuesHolder.ofFloat(View.SCALE_Y, 0.8f, 1.2f)
)
scaleAnimator.duration = 800
scaleAnimator.repeatCount = ValueAnimator.INFINITE
scaleAnimator.repeatMode = ValueAnimator.REVERSE

// Create rotate animation
val rotateAnimator = ObjectAnimator.ofFloat(customSpinner, View.ROTATION, 0f, 360f)
rotateAnimator.duration = 1500
rotateAnimator.repeatCount = ValueAnimator.INFINITE

// Play both animations together
val animatorSet = AnimatorSet()
animatorSet.playTogether(scaleAnimator, rotateAnimator)
animatorSet.start()

For this, your layout would have a simple View (like an ImageView or a shaped View):

<View
    android:id="@+id/customSpinnerView"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:background="@drawable/round_spinner_shape" /> <!-- A simple circle shape drawable -->

Using the Custom Indeterminate ProgressBar

To show/hide it, just toggle its visibility:

// Show the spinner
customIndeterminateBar.visibility = View.VISIBLE

// Hide when task is done
customIndeterminateBar.visibility = View.GONE

Pro Tips

  • For theme consistency, use ?attr/colorPrimary instead of hardcoded colors—this will automatically adapt to light/dark themes.
  • Adjust animation durations to match your app's feel (faster for snappy apps, slower for more relaxed UIs).
  • For accessibility, make sure to set android:contentDescription so screen readers can announce what the progress bar is for.

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

火山引擎 最新活动