Home » Android » Android: set color programmatically to ProgressBar

Android: set color programmatically to ProgressBar

Posted by: admin June 16, 2020 Leave a comment

Questions:

I would like to set color programmatically to the progress bar primaryProgress, secondaryProgress as the color will be changed according to the background color of the screen.

Code:

LayerDrawable progressDrawable = (LayerDrawable) ProgressBar1.getProgressDrawable();
Drawable backgroundColor = progressDrawable.getDrawable(0);
Drawable secondaryColor = progressDrawable.getDrawable(1);
Drawable primaryColor = progressDrawable.getDrawable(2);

final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 };
primaryColor = new ShapeDrawable(new RoundRectShape(roundedCorners, null, null));
secondaryColor = new ShapeDrawable(new RoundRectShape(roundedCorners, null, null));

primaryColor.setColor((Color.rgb(color_normal[0], color_normal[1], color_normal[2])), null);
secondaryColor.setColor((Color.rgb(color_normal[0], color_normal[1], color_normal[2])), null);

progressDrawable.setDrawableByLayerId(progressDrawable.getId(2), new ClipDrawable(primaryColor, Gravity.LEFT, ClipDrawable.HORIZONTAL));

...

Edit:

** the color code here are for testing only. Afterwards the colorcode will be referenced to other part for updates accordingly

    secondaryColor.setColorFilter((Color.rgb(255, 0, 0)), PorterDuff.Mode.SRC_OVER);
    primaryColor.setColorFilter((Color.rgb(0, 255, 213)), PorterDuff.Mode.SRC_OVER);        

    progressDrawable.setDrawableByLayerId(progressDrawable.getId(2), new ClipDrawable(primaryColor, Gravity.LEFT, ClipDrawable.HORIZONTAL));
    progressDrawable.setDrawableByLayerId(progressDrawable.getId(1), new ClipDrawable(secondaryColor, Gravity.LEFT, ClipDrawable.HORIZONTAL));
    ProgressBar1.setProgressDrawable(progressDrawable); 
    ProgressBar1.setProgress(progress);
    ProgressBar1.setSecondaryProgress(secondaryProgress);

Question:

It underlines in red for primanyColor.setColor and reports that The method setColor(int, null) is undefined for the type Drawable .

How could I modify the above codes to make it works? Thanks!

How to&Answers:

To set colors for Drawable use Drawable.setColorFilter. like:

primaryColor.setColorFilter((Color.rgb(0,128,0)), 
                                                 PorterDuff.Mode.SRC_OVER);        

Answer:

Here is the code for changing the color of ProgressBar by programatically for min sdk version 21 and above

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

Answer:

What you can do is make your layer-list drawable via xml first (meaning a background as the first layer, a drawable that represents secondary progress as the second layer, and another drawable that represents the primary progress as the last layer), then change the color on the code by doing the following:

public void setPrimaryProgressColor(int colorInstance) {
      if (progressBar.getProgressDrawable() instanceof LayerDrawable) {
        Log.d(mLogTag, "Drawable is a layer drawable");
        LayerDrawable layered = (LayerDrawable) progressBar.getProgressDrawable();
        Drawable circleDrawableExample = layered.getDrawable(<whichever is your index of android.R.id.progress>);
        circleDrawableExample.setColorFilter(colorInstance, PorterDuff.Mode.SRC_IN);
        progressBar.setProgressDrawable(layered);
    } else {
        Log.d(mLogTag, "Fallback in case it's not a LayerDrawable");
        progressBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
    }
}

This method will give you the best flexibility of having the measurement of your original drawable declared on the xml, WITH NO MODIFICATION ON ITS STRUCTURE AFTERWARDS, especially if you need to have the xml file screen folder specific, then just modifying ONLY THE COLOR via the code. No re-instantiating a new ShapeDrawable from scratch whatsoever.