Set android shape color programmatically
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Android, a shape background defined in XML is usually a GradientDrawable at runtime. If you want to change its fill color programmatically, the normal pattern is to get the drawable, make sure you are not mutating a shared instance, cast it to GradientDrawable, and call setColor.
Start With a Shape Drawable
A typical XML shape might look like this:
Attach it as a background in layout XML:
At runtime, that background is typically a GradientDrawable.
Change the Color in Kotlin
Here is the common Kotlin pattern:
Two parts matter here:
- '
as GradientDrawablegives access tosetColor' - '
mutate()prevents changes from affecting other views that use the same drawable resource instance'
Without mutate(), changing one background can unexpectedly recolor other views that share that same XML drawable.
Change the Color in Java
The equivalent Java code looks like this:
This is the same operation, just in Java syntax.
Create the Shape Entirely in Code
If you do not want an XML drawable at all, you can create the shape programmatically:
This is useful when the shape itself is dynamic, not just the color.
Use Theme Colors Instead of Hardcoded Values
In real apps, colors often come from resources rather than inline hex strings:
That keeps your UI consistent with theming and makes dark mode or design-system updates much easier.
What if the Background Is Not a GradientDrawable
Not every background drawable is a shape XML. It might be:
- a
ColorDrawable - a
RippleDrawable - a
StateListDrawable - a layered drawable
If the cast fails, inspect the actual drawable type before assuming GradientDrawable.
For example:
Sometimes the shape is wrapped inside another drawable, especially when ripple effects or state selectors are involved.
Update Stroke or Corners Too
Once you have a GradientDrawable, you can change more than the fill color:
That makes programmatic shape updates useful for error states, selection highlights, and theme changes.
Common Pitfalls
The biggest pitfall is forgetting mutate(). Drawable resources are often shared, so without mutation you can accidentally recolor other views.
Another common issue is casting blindly to GradientDrawable when the actual runtime drawable is something else, such as a ripple or selector wrapper.
People also often hardcode colors in code when the app already has theme or resource colors defined. That makes long-term UI maintenance harder.
Finally, changing the drawable object does not help if the view later receives a different background from state changes or style updates. Make sure you are modifying the drawable that is actually in use.
Summary
- Most XML shape backgrounds can be changed at runtime through
GradientDrawable.setColor. - Call
mutate()before editing to avoid affecting shared drawable instances. - Use resource or theme colors instead of hardcoded values when possible.
- Verify the runtime drawable type before casting.
- Programmatic drawables are a good choice when the shape itself is dynamic.

