WhiteTigerK
WhiteTigerK

Reputation: 7051

How to change progress bar's progress color in Android

I'm using an horizontal progress bar in my Android application, and I want to change its progress color (which is Yellow by default). How can I do it using code (not XML)?

Upvotes: 610

Views: 815796

Answers (30)

halitSen
halitSen

Reputation: 11

You can use this :

progressBar.indeterminateTintList = 
ColorStateList.valueOf(ContextCompat.getColor(context,R.color.white))

Upvotes: 0

Nasib
Nasib

Reputation: 1579

For default ( indeterminate )

add

android:indeterminateTint="@color/white"

for determinate

    android:progressTint="@color/color_1"

    //OR
    progressBar.getProgressDrawable().setColorFilter( PorterDuffColorFilter(Color.RED,android.graphics.PorterDuff.Mode.SRC_IN));

Upvotes: 20

Mohammed Alomair
Mohammed Alomair

Reputation: 395

If any one want to change color programmatically:

progressBar.progressTintList = ColorStateList.valueOf(Color.RED)

Upvotes: 5

AI Shakil
AI Shakil

Reputation: 1762

Trust me, the easiest solution is just paste this inside progressBar :

android:indeterminateTint="@android:color/white"

Upvotes: 30

Mark Nashat
Mark Nashat

Reputation: 768

Add in ProgressBar inside of Xml

For SDK ver 21 and above

android:indeterminateTint="@color/red"

Upvotes: 24

Abhishek Charismatic
Abhishek Charismatic

Reputation: 366

I know I am late but this is the easiest solution if you only want to change the color of your progress bar, In your theme, simply add,

@color/your_color

colorSecondary will change you progress color throughout.

Upvotes: 0

Mughil
Mughil

Reputation: 715

For SDK ver 21 and above

android:indeterminateTint="@color/orange"

in XML Works for me, is easy enough.

Upvotes: 25

Mahozad
Mahozad

Reputation: 24682

It seems that an indeterminate linear progress indicator can be made multicolor in newer versions of material design library.

Making animation type of the progress bar contiguous achieves this.

  • In the layout with this attribute:
    app:indeterminateAnimationType
    
  • or programmatically with this method:
    setIndeterminateAnimationType()
    

Refer here for more info.

Upvotes: 0

Andrii Turkovskyi
Andrii Turkovskyi

Reputation: 29458

Since method public void setColorFilter(@ColorInt int color, @NonNull PorterDuff.Mode mode) is deprecated, I use such form:

progressBar.indeterminateDrawable.colorFilter =
            PorterDuffColorFilter(ContextCompat.getColor(this, R.color.black), PorterDuff.Mode.SRC_IN)

Upvotes: 2

Amirhossein Ghasemi
Amirhossein Ghasemi

Reputation: 22168

Simply use:

DrawableCompat.setTint(progressBar.getIndeterminateDrawable(),yourColor)

Upvotes: 10

Satyam Patil
Satyam Patil

Reputation: 161

The most simple way of changing the foreground and background colour of a progress bar is

<ProgressBar
                        style="@android:style/Widget.ProgressBar.Horizontal"
                        android:id="@+id/pb_main"
                        android:layout_width="match_parent"
                        android:layout_height="8dp"
                        android:progress="30"
                        android:progressTint="#82e9de"
                        android:progressBackgroundTint="#82e9de"
                        />

just add

                        android:progressTint="#82e9de" //for foreground colour
                        android:progressBackgroundTint="#82e9de" //for background colour

Upvotes: 14

Devinder Jhinjer
Devinder Jhinjer

Reputation: 655

This works for me. It also works for lower version too. Add this to your syles.xml

<style name="ProgressBarTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorAccent">@color/colorPrimary</item>
</style>

And use it like this in xml

<ProgressBar
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:theme="@style/ProgressBarTheme"
   />

Upvotes: 53

Mohammad Fneish
Mohammad Fneish

Reputation: 989

simply use:

PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
    mode = PorterDuff.Mode.MULTIPLY;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
    progressBar.setProgressBackgroundTintList(ColorStateList.valueOf(Color.RED));
} else {
    Drawable progressDrawable;
    progressDrawable = (progressBar.isIndeterminate() ? progressBar.getIndeterminateDrawable() : progressBar.getProgressDrawable()).mutate();
    progressDrawable.setColorFilter(context.getResources().getColor(Color.RED), mode);
    progressBar.setProgressDrawable(progressDrawable);
}

Upvotes: 8

FFirmenich
FFirmenich

Reputation: 5921

This is not programmatically but I think it could help a lot of people anyway.
I tried a lot and the most efficient way was to add this lines to my ProgressBar in the .xml File:

            android:indeterminate="true"
            android:indeterminateTintMode="src_atop"
            android:indeterminateTint="@color/secondary"

So in the end this code did it for me:

<ProgressBar
            android:id="@+id/progressBar"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:layout_marginTop="50dp"
            android:layout_marginBottom="50dp"
            android:visibility="visible"
            android:indeterminate="true"
            android:indeterminateTintMode="src_atop"
            android:indeterminateTint="@color/secondary">

This solution works for API 21+

Upvotes: 564

John
John

Reputation: 1543

To change horizontal ProgressBar color (in kotlin):

fun tintHorizontalProgress(progress: ProgressBar, @ColorInt color: Int = ContextCompat.getColor(progress.context, R.color.colorPrimary)){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        progress.progressTintList = ColorStateList.valueOf(color)
    } else{
        val layerDrawable = progress.progressDrawable as? LayerDrawable
        val progressDrawable = layerDrawable?.findDrawableByLayerId(android.R.id.progress)
        progressDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
    }
}

To change indeterminate ProgressBar color:

fun tintIndeterminateProgress(progress: ProgressBar, @ColorInt color: Int = ContextCompat.getColor(progress.context, R.color.colorPrimary)){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        progress.indeterminateTintList = ColorStateList.valueOf(color)
    } else {
        (progress.indeterminateDrawable as? LayerDrawable)?.apply {
            if (numberOfLayers >= 2) {
                setId(0, android.R.id.progress)
                setId(1, android.R.id.secondaryProgress)
                val progressDrawable = findDrawableByLayerId(android.R.id.progress).mutate()
                progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
            }
        }
    }
}

And it finally normally tint pre-lollipop progressBars

tinted progress on api 19

Upvotes: 10

Richard Le Mesurier
Richard Le Mesurier

Reputation: 29762

Posted to add info about PaulieG's answer, since ateiob asked me to explain something...


I can say that there is (or at least was, at the time of writing when I looked at that current version of Android source code) a bug/issue/optimisation in the ProgressBar code that ignores an attempt to set the progress to a value it is already at.

  • i.e. if progress = 45, and you try to set it to 45, the code will do nothing, and will not redraw the progress.

After calling ProgressBar.setProgressDrawable(), your progress bar will be blank (because you changed the drawable part).

This means you need to set the progress, and redraw it. But if you just set the progress to a preserved value, it will do nothing.

You must set it to 0 first, then to the "old" value again, and the bar will redraw.


So to summarise:

  • preserve the "old" progress value
  • update the drawable / colour (makes bar blank)
  • reset the progress to 0 (otherwise next line does nothing)
  • reset the progress to the "old" value (fixes bar)
  • invalidate

Below is a method I have that does this:

protected void onResume()
{
    super.onResume();
    progBar = (ProgressBar) findViewById(R.id.progress_base);

    int oldProgress = progBar.getProgress();

    // define new drawable/colour
    final float[] roundedCorners = new float[]
        { 5, 5, 5, 5, 5, 5, 5, 5 };
    ShapeDrawable shape = new ShapeDrawable(new RoundRectShape(
        roundedCorners, null, null));
    String MyColor = "#FF00FF";
    shape.getPaint().setColor(Color.parseColor(MyColor));
    ClipDrawable clip = new ClipDrawable(shape, Gravity.LEFT,
        ClipDrawable.HORIZONTAL);
    progBar.setProgressDrawable(clip);

    progBar.setBackgroundDrawable(getResources().getDrawable(
        android.R.drawable.progress_horizontal));

    // work around: setProgress() ignores a change to the same value
    progBar.setProgress(0);
    progBar.setProgress(oldProgress);

    progBar.invalidate();
}

As far as HappyEngineer's solution, I think it was a similar workaround, to manually set the "progress" offset. In either case, the above code should work for you.

Upvotes: 7

Rasoul Miri
Rasoul Miri

Reputation: 12222

All API

if use all API just create the theme in style

style.xml

<resources>

    //...

    <style name="progressBarBlue" parent="@style/Theme.AppCompat">
        <item name="colorAccent">@color/blue</item>
    </style>

</resources>

and use in progress

<ProgressBar
    ...
    android:theme="@style/progressBarBlue" />

API level 21 and higher

if used in API level 21 and higher just use this code:

<ProgressBar
   //...
   android:indeterminate="true"
   android:indeterminateTintMode="src_atop"
   android:indeterminateTint="@color/secondary"/>

Upvotes: 69

Null Pointer Exception
Null Pointer Exception

Reputation: 1583

ProgressBar freeRamPb = findViewById(R.id.free_ram_progress_bar);

freeRamPb.getProgressDrawable().setColorFilter(
Color.BLUE, android.graphics.PorterDuff.Mode.SRC_IN);

Upvotes: 4

Al&#233;cio Carvalho
Al&#233;cio Carvalho

Reputation: 13657

Use the android.support.v4.graphics.drawable.DrawableCompat:

            Drawable progressDrawable = progressBar.getIndeterminateDrawable();
            if (progressDrawable  != null) {
                Drawable mutateDrawable = progressDrawable.mutate();
                DrawableCompat.setTint(mutateDrawable, primaryColor);
                progressBar.setProgressDrawable(mutateDrawable);
            }

Upvotes: 7

Debasish Ghosh
Debasish Ghosh

Reputation: 1887

THis is what i did. Worked.

ProgressBar:

<ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="4"
            android:indeterminateDrawable="@drawable/progressdrawable"
           />

progressdrawable.xml:
Here use gradient to change colour as you like. And android:toDegrees="X" increse the value of X and progressbar rotate fast. Decrease and it rotate slow.Customize according to your needs.

<?xml version="1.0" encoding="utf-8"?>
     <rotate xmlns:android="http://schemas.android.com/apk/res/android"
            android:duration="4000"
            android:fromDegrees="0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="360" >

            <shape
                android:innerRadius="20dp"
                android:shape="ring"
                android:thickness="4dp"
                android:useLevel="false" >
                <size
                    android:height="48dp"
                    android:width="48dp" />

                <gradient
                    android:centerColor="#80ec7e2a"
                    android:centerY="0.5"
                    android:endColor="#ffec7e2a"
                    android:startColor="#00ec7e2a"
                    android:type="sweep"
                    android:useLevel="false" />
            </shape>

        </rotate>

sample: enter image description here

Upvotes: 24

Torben Kohlmeier
Torben Kohlmeier

Reputation: 6783

For a horizontal ProgressBar, you can use a ColorFilter, too, like this:

progressBar.getProgressDrawable().setColorFilter(
    Color.RED, android.graphics.PorterDuff.Mode.SRC_IN);

Red ProgressBar using color filter

Note: This modifies the appearance of all progress bars in your app. To only modify one specific progress bar, do this:

Drawable progressDrawable = progressBar.getProgressDrawable().mutate();
progressDrawable.setColorFilter(Color.RED, android.graphics.PorterDuff.Mode.SRC_IN);
progressBar.setProgressDrawable(progressDrawable);

If progressBar is indeterminate then use getIndeterminateDrawable() instead of getProgressDrawable().

Since Lollipop (API 21) you can set a progress tint:

progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));

Red ProgressBar using progress tint

Upvotes: 543

Adriano Moutinho
Adriano Moutinho

Reputation: 601

You can try to change your Styles, Themes, or using android:indeterminateTint="@color/yourColor" anywhere you want, but there's just one way o doing that will work on any Android SKD version:

If you progress bar is not indeterminate, please use:

progressBar.getProgressDrawable().setColorFilter(ContextCompat.getColor(context, R.color.yourColor), PorterDuff.Mode.SRC_IN );

If you progress bar is indeterminate, please use:

progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), R.color.yourColor), PorterDuff.Mode.SRC_IN );

It's sad that Android is such a mess!

Upvotes: 19

Naveed Ahmad
Naveed Ahmad

Reputation: 6747

Simplest Solution if you want to change the colour in the layout xml file, use the below code and use indeterminateTint property for your desired color.

    <ProgressBar
      android:id="@+id/progressBar"
      style="?android:attr/progressBarStyle"
      android:layout_width="wrap_content"
      android:indeterminate="true"
      android:indeterminateTintMode="src_atop"
      android:indeterminateTint="#ddbd4e"
      android:layout_height="wrap_content"
      android:layout_marginBottom="20dp"
      android:layout_alignParentBottom="true"
      android:layout_centerHorizontal="true" />

Upvotes: 15

Arnav Rao
Arnav Rao

Reputation: 7002

Horizontal progress bar custom material style :

To change color of background and progress of horizontal progress bar.

<style name="MyProgressBar" parent="@style/Widget.AppCompat.ProgressBar.Horizontal">
    <item name="android:progressBackgroundTint">#69f0ae</item>
    <item name="android:progressTint">#b71c1c</item>
    <item name="android:minWidth">200dp</item>
</style>

Apply it to progress bar by setting style attribute, for custom material styles and custom progress bar check http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples

Upvotes: 7

S.Javed
S.Javed

Reputation: 403

This solution worked for me :

<style name="Progressbar.White" parent="AppTheme">
    <item name="colorControlActivated">@color/white</item>
</style>

<ProgressBar
    android:layout_width="@dimen/d_40"
    android:layout_height="@dimen/d_40"
    android:indeterminate="true"
    android:theme="@style/Progressbar.White"/>

Upvotes: 13

Naveen Kumar M
Naveen Kumar M

Reputation: 7557

Here is the code for changing the color of ProgressBar by programatically.

ProgressBar progressBar = (ProgressBar) findViewById(R.id.pb_listProgressBar);
int colorCodeDark = Color.parseColor("#F44336");
progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorCodeDark));

Upvotes: 4

MOH3N
MOH3N

Reputation: 1065

This worked for me :

<ProgressBar
 android:indeterminateTint="#d60909"
 ... />

Upvotes: 43

DeepakPanwar
DeepakPanwar

Reputation: 1389

It is so simple using attr , if you are dealing with multistyle apps:

try this way:

Declare below attribute attrs.xml

 <attr name="circularProgressTheme" format="reference"></attr>

Paste below code in styles.xml

 <style name="ProgressThemeWhite" parent="ThemeOverlay.AppCompat.Light">
        <item name="colorAccent">#FF0000</item>
    </style>

    <style name="circularProgressThemeWhite">
        <item name="android:theme">@style/ProgressThemeWhite</item>
    </style>


  <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">

   <item name="circularProgressTheme">@style/circularProgressThemeWhite</item>

 </style>

use progress bar like below

  <ProgressBar
        style="?attr/circularProgressTheme"
        android:id="@+id/commonProgress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="visible"/>

Upvotes: 3

Calin
Calin

Reputation: 6867

One more little thing, the theme solution does work if you inherit a base theme, so for app compact your theme should be:

<style name="AppTheme.Custom" parent="@style/Theme.AppCompat">
    <item name="colorAccent">@color/custom</item>
</style>

And then set this in the progress bar theme

<ProgressBar
    android:id="@+id/progressCircle_progressBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:theme="@style/AppTheme.Custom"
    android:indeterminate="true"/>

Upvotes: 9

Birendra Singh
Birendra Singh

Reputation: 860

Horizontal ProgressBar uses rectangle shape drawable for background, ClipDrawable constructed from rectangle shape for progresses (primary & secondary). Tinting changes colors to some tint. If you want targeted colors for all three separately then you can use ProgressBar.setProgressDrawable() as following:

    LayerDrawable progressBarDrawable = new LayerDrawable(
        new Drawable[]{
                new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
                            new int[]{Color.parseColor("#ff0000ff"),Color.parseColor("#ff0000ff")}),

                new ClipDrawable(
                            new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
                                    new int[]{Color.parseColor("#ff00ff00"),Color.parseColor("#ff00ff00")}),
                            Gravity.START,
                            ClipDrawable.HORIZONTAL),

                new ClipDrawable(
                        new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
                                new int[]{Color.parseColor("#ffff0000"),Color.parseColor("#ffff0000")}),
                        Gravity.START,
                        ClipDrawable.HORIZONTAL)
            });

    progressBarDrawable.setId(0,android.R.id.background);
    progressBarDrawable.setId(1,android.R.id.secondaryProgress);
    progressBarDrawable.setId(2,android.R.id.progress);
    ((ProgressBar)findViewById(R.id.progressBar)).setProgressDrawable(progressBarDrawable);

Note that order of drawable layers is important while initializing LayerDrawable. First drawable should be for background. As per my experiment switching ids does not work. If you set padding to progressbar then this approach will not work. If you need padding then you can use a container for the progressbar such as a LinearLayout.

Upvotes: 2

Related Questions