9

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!

pearmak
  • 4,979
  • 15
  • 64
  • 122
  • Do `primaryColor.getPaint().setColor(Color.rgb(color_normal[0], color_normal[1], color_normal[2]));` – M D Jul 03 '15 at 06:32
  • Thanks. I have tried that too and that gives error: `The method getPaint() is undefined for the type Drawable` – pearmak Jul 03 '15 at 06:33
  • 1
    @pearmak: ok Then do it using `primaryColor.setColorFilter` method – ρяσѕρєя K Jul 03 '15 at 06:34
  • make it `ShapeDrawable primaryColor` then – M D Jul 03 '15 at 06:34
  • I think you can get something from here!!-----> http://www.geeks.gallery/horizontal-and-circular-progress-bar-in-android/ http://www.101apps.co.za/articles/android-s-progress-bars.html http://www.tiemenschut.com/how-to-customize-android-progress-bars/ – Chaudhary Amar Jul 03 '15 at 06:36
  • @AmarbirSingh: Thanks for the link. I have also researched such 2 links before but they are through xml instead of programmatically which seem unable to serve the request of changing colors according to the background color of screen dynamically. – pearmak Jul 03 '15 at 06:41
  • @ρяσѕρєяK: thanks for your direction, I have tried using `setColorFilter` as advised, with the rule that secondaryprogress must be greater than the primanyprogress, I dont know why it just showing the secondaryprogress (red) only. Pls see the updated code in the questions... thanks a lot! – pearmak Jul 03 '15 at 06:50
  • @pearmak: try some different color for primany like `(0,128,0)` – ρяσѕρєя K Jul 03 '15 at 06:53
  • http://stackoverflow.com/questions/10951978/change-progressbar-color-through-code-only-in-android – Chaudhary Amar Jul 03 '15 at 06:53
  • 1
    @ρяσѕρєяK: Thanks a lot! It is working now! It would be pleasure if you post an answer as that in the Edit part – pearmak Jul 03 '15 at 07:08

3 Answers3

5

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));
Naveen Kumar M
  • 7,497
  • 7
  • 60
  • 74
3

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.

Pier Betos
  • 1,038
  • 9
  • 17
  • This will crash my app when using inside a ViewHolder. – Henrique de Sousa Jul 24 '16 at 23:58
  • 3 things: - Make sure your progressbar is not null - Make sure your progressbar is using a layer-list drawable on it's xml layout - Make sure that your layerlist has each item identified inside the xml: – Pier Betos Jul 25 '16 at 00:06
  • Yeah, progressbar is not null. And yes, my progressbar is using a layer-list drawable. And yes, unfortunately it has both 3 :( Thanks anyway. I solved it using `progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));` – Henrique de Sousa Jul 25 '16 at 00:10
  • Perfect solution for `layer-list` drawable. – Chintan Shah Apr 11 '17 at 10:26
  • instead using layered.getDrawable(), use layered.findDrawableByLayerId(android.R.id.progress) which is less error prone – Tinfu Dec 08 '17 at 07:17
2

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

primaryColor.setColorFilter((Color.rgb(0,128,0)), 
                                                 PorterDuff.Mode.SRC_OVER);        
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213