How to change ProgressBar's progress indicator color in Android
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Android's default ProgressBar uses the theme's accent color for the progress indicator. To customize this color, you can use XML theme attributes, a custom drawable, or change it programmatically at runtime. The best approach depends on whether you need a static color or one that changes dynamically based on state. All three methods work for both determinate and indeterminate progress bars.
XML Theme Attribute (Simplest)
The quickest way to change the progress color is via the android:progressTint attribute (API 21+):
For an indeterminate spinner, use android:indeterminateTint:
Custom Drawable (Full Control)
Create a drawable XML file at res/drawable/custom_progress.xml for complete control over colors, gradients, and shapes:
Apply it to the ProgressBar:
The @android:id/background, @android:id/secondaryProgress, and @android:id/progress layer IDs are required for Android to map each layer correctly.
Programmatic Approach
Change the color at runtime using setProgressTintList (API 21+):
For API levels below 21, use DrawableCompat:
The mutate() call clones the drawable so that color changes do not affect other views sharing the same drawable resource.
Changing Color Based on Progress Value
A common pattern is changing color as progress increases (green to red):
Using Theme Overlay
Apply a color via your app theme to affect all progress bars:
Override for a specific ProgressBar using android:theme:
Common Pitfalls
- Forgetting
mutate()on shared drawables: Withoutmutate(), callingsetTintorsetColorFilteron a progress drawable changes the color for every view using that drawable. Always callmutate()first when modifying drawables programmatically. - Using
progressTintbelow API 21: Theandroid:progressTintXML attribute andsetProgressTintList()require API 21+. On older devices, useDrawableCompat.setTint()from the AndroidX library or a custom drawable XML. - Missing layer IDs in custom drawables: If you omit
@android:id/progressor@android:id/backgroundfrom your layer-list, the ProgressBar cannot identify which layer to clip and the bar appears empty or fully filled. - Indeterminate vs determinate tint:
android:progressTintonly affects the determinate bar. For the spinning indeterminate animation, you must useandroid:indeterminateTintinstead. - RTL layout issues: Custom progress drawables using
ClipDrawabledefault to left-to-right clipping. For RTL support, setandroid:autoMirrored="true"on the drawable or useandroid:layoutDirectionon the ProgressBar.
Summary
- Use
android:progressTintfor a quick color change on API 21+ - Create a custom
layer-listdrawable for full control over background, secondary progress, and primary progress colors - Use
setProgressTintList()orDrawableCompat.setTint()for runtime color changes - Always call
mutate()before modifying shared drawables to avoid affecting other views - Use
android:indeterminateTintfor spinner-style progress bars - Apply
android:themewithcolorAccentto restyle individual progress bars without a custom drawable

