如何更改小部件中的进度条颜色?

问题描述 投票:0回答:5

有什么方法可以在运行时更改应用程序小部件中的

ProgressBar
的颜色吗?

这就是

ProgressBar
进度值的更新方式:

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

不幸的是,

RemoteViews
类不允许我们为
ProgressBar
设置颜色过滤器,甚至不同的进度可绘制。

任何想法将不胜感激。

android android-appwidget
5个回答
4
投票

我遇到了类似的问题,在自定义通知布局中对 ProgressBar 进行着色。 我已经成功地使用反射 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();
        }
    }

0
投票

在 ProgressBar XML 中添加此行:

android:progressDrawable="@drawable/progressbar"

现在创建 Progressbar.xml 可绘制对象:

<?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>

参见参考: Android更改水平进度条颜色


0
投票

例如,您有 ProgressDrawable (图层列表):

  • @android:id/背景 - 纯色
  • @android:id/progress - 应该以编程方式更新

你可以使用这个技巧:

  1. 您可以在 ProgressBar 后面创建 ImageView 并使用 setInt(id, "setColorFilter", color) 更新其颜色,而不是进度层
  2. 将 android:rotation="180" 添加到 xml 文件中的进度条
  3. 您应该设置“最大 - 进度”值,而不是设置进度值
  4. 现在进度条用作背景

0
投票

Oleksandr 给出了一个很好的答案,以防万一您使用不确定的进度条,该方法将不起作用。

这里是包含所有不同方法可供使用的代码。

      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.
        }
      }

0
投票

从 SDK 级别 31 开始,您可以在 RemoteViews 中使用 setColorStateList 方法

yourRemoteViews.setColorStateList(R.id.progressbar, "setProgressTintList", yourColorStateList)

但是对于旧版本,您必须使用反射。

© www.soinside.com 2019 - 2024. All rights reserved.