Android
Drawable
Color Customization
Android Development
Mobile App Design

How to change colors of a Drawable in Android?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Changing a drawable's color in Android usually means tinting it rather than editing the underlying asset. The right API depends on what you are coloring, but for most runtime changes the normal approach is to obtain the drawable, call mutate(), and apply a tint or color filter.

Tint a Drawable in Code

For many modern cases, DrawableCompat.setTint is the cleanest option.

kotlin
1import android.graphics.Color
2import androidx.core.content.ContextCompat
3import androidx.core.graphics.drawable.DrawableCompat
4
5val drawable = ContextCompat.getDrawable(context, R.drawable.ic_star)?.mutate()
6if (drawable != null) {
7    DrawableCompat.setTint(drawable, Color.RED)
8    imageView.setImageDrawable(drawable)
9}

mutate() matters because drawable resources can share constant state. Without it, tinting one usage can unexpectedly recolor another place that uses the same resource.

Use a Color State List for Multiple States

If the color should change based on enabled, pressed, or selected state, a ColorStateList is usually better than setting one fixed tint in code.

xml
1<selector xmlns:android="http://schemas.android.com/apk/res/android">
2    <item android:color="#FF0000" android:state_pressed="true" />
3    <item android:color="#888888" />
4</selector>

Then apply it in code or XML where the view supports tinting. This keeps visual state rules declarative instead of scattering them across event handlers.

XML Shapes Are Different

If the drawable is an XML shape rather than an image or vector, changing color can be as simple as editing the shape fill or applying a tint to the view that uses it.

Example shape drawable:

xml
1<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
2    <solid android:color="#2196F3" />
3    <corners android:radius="8dp" />
4</shape>

If the color is static and known up front, changing the XML resource may be the cleanest solution. If it changes at runtime, use tinting or generate the shape dynamically.

View Tint APIs Can Be Simpler

Sometimes you do not need to touch the drawable directly. If the drawable is being shown inside an ImageView, view-level tint can be enough.

kotlin
imageView.setColorFilter(Color.GREEN)

or with support libraries and modern APIs:

kotlin
imageView.imageTintList = android.content.res.ColorStateList.valueOf(Color.GREEN)

This is simpler when the color change is only relevant to one view instance and you do not need to reuse the tinted drawable elsewhere.

Pick the Right Technique

A practical rule is:

  • use tinting for runtime recoloring of existing assets
  • use ColorStateList for state-driven colors
  • edit XML directly for static shape colors
  • use view tint when only one displayed instance needs recoloring

That keeps the implementation aligned with the real source of the color change instead of forcing one technique everywhere.

Vector Assets Benefit the Most

Tinting works especially well with vector drawables because one asset can be reused across themes, states, and surfaces without generating multiple colored bitmap files. That is one reason Android design systems often standardize on vector icons plus tint rather than keeping many pre-colored image variants in the resources folder.

Common Pitfalls

  • Forgetting mutate() and accidentally recoloring shared drawable state.
  • Using a fixed runtime tint when the real requirement is state-based coloring.
  • Editing the asset file itself when the problem is only dynamic presentation.
  • Applying an old color filter pattern where a proper tint API would be clearer.
  • Expecting every drawable type to behave identically under tinting without testing the specific asset.

Summary

  • In Android, changing a drawable's color is usually done through tinting.
  • 'DrawableCompat.setTint plus mutate() is a common safe default.'
  • Use ColorStateList when color depends on UI state.
  • Static XML shapes are easiest to recolor in their resource definition.
  • Choose between drawable tint and view tint based on where the color behavior really belongs.

Course illustration
Course illustration

All Rights Reserved.