4

Is there any way to change the color of the ProgressBar residing in the app widget at runtime?

This is how the ProgressBar progress value is updated:

RemoteViews views = new RemoteViews( context.getPackageName(), R.layout.widget );
views.setProgressBar( R.id.progressbar, 100, 10, false );
...
appWidgetManager.updateAppWidget( widgetID, views );

Unfortunately, the RemoteViews class does not allow us to set a color filter or even a different progress drawable for ProgressBar.

Any ideas would be appreciated.

davee44
  • 357
  • 3
  • 10

4 Answers4

4

I have encountered with similar problem to tint ProgressBar inside custom notification layout. I have managed to do it using reflection API:

    Method setTintMethod = null;
    try {
        setTintMethod = RemoteViews.class.getMethod("setProgressTintList", int.class, ColorStateList.class);
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    if (setTintMethod != null) {
        try {
            setTintMethod.invoke(mYourRemoteViews, R.id.your_progress_bar_id, ColorStateList.valueOf(yourColor));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
Oleksandr Albul
  • 1,611
  • 1
  • 23
  • 31
0

Add this line in the ProgressBar XML:

android:progressDrawable="@drawable/progressbar"

And now Create the progressbar.xml drawable:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
    <shape>
        <corners android:radius="5dip" />
        <gradient
                android:startColor="#ff9d9e9d"
                android:centerColor="#ff5a5d5a"
                android:centerY="0.75"
                android:endColor="#ff747674"
                android:angle="270"
        />
    </shape>
</item>

<item android:id="@android:id/secondaryProgress">
    <clip>
        <shape>
            <corners android:radius="5dip" />
            <gradient
                    android:startColor="#80ffd300"
                    android:centerColor="#80ffb600"
                    android:centerY="0.75"
                    android:endColor="#a0ffcb00"
                    android:angle="270"
            />
        </shape>
    </clip>
</item>
<item
    android:id="@android:id/progress"
>
    <clip>
        <shape>
            <corners
                android:radius="5dip" />
            <gradient
                android:startColor="#33FF33"
                android:endColor="#008000"
                android:angle="270" />
        </shape>
    </clip>
</item>

</layer-list>

See reference: Android change Horizonal Progress bar color

Community
  • 1
  • 1
RonM
  • 187
  • 3
0

For example you have progressDrawable (layer-list) with:

  • @android:id/background - solid color
  • @android:id/progress - should update programatically

You can use the trick:

  1. Instead of progress layer you can create ImageView behind progressBar and update it color using setInt(id, "setColorFilter", color)
  2. Add android:rotation="180" to progressBar in xml file
  3. Instead of setting a progress value you should set "max - progress" value
  4. Now the progressBar used as a background
Andrey Tuzov
  • 143
  • 1
  • 7
0

Oleksandr has given a great answer, just in case you are using indeterministic progressbar, that method will not work for it.

Here's code with all different methods available to use.

      Method setInDeterminateProgressTintMethod = null;
      Method setProgressTintMethod = null;
      Method setProgressBackgroundTintMethod = null;
      try {

        setInDeterminateProgressTintMethod = RemoteViews.class.getMethod("setProgressIndeterminateTintList", int.class, ColorStateList.class);
        setProgressTintMethod = RemoteViews.class.getMethod("setProgressTintList", int.class, ColorStateList.class);
        setProgressBackgroundTintMethod = RemoteViews.class.getMethod("setProgressBackgroundTintList", int.class, ColorStateList.class);

      } catch (SecurityException|NoSuchMethodException ex) {
        ex.printStackTrace();
        // do nothing if we can not apply progress bar tint.
      }
      if (setInDeterminateProgressTintMethod != null) {
        try {
          Log.d(TAG, "Invoking setTintMethod");
          setInDeterminateProgressTintMethod.invoke(remoteViews, resId, ColorStateList.valueOf(Color.parseColor("#yourhexcolor")));
          setProgressTintMethod.invoke(remoteViews, resId, ColorStateList.valueOf(Color.parseColor("#yourhexcolor")));
          setProgressBackgroundTintMethod.invoke(remoteViews, resId, ColorStateList.valueOf(Color.parseColor("#yourhexcolor")));
        } catch (IllegalAccessException|InvocationTargetException ex) {
          Log.d(TAG, "Exception in setting tint for progressbar: "+ ex.getMessage());
          ex.printStackTrace(); // do nothing if we can not apply progress bar tint.
        }
      }
Ankush Chugh
  • 164
  • 8