在Android中仅通过代码更改进度条颜色

79

我有一个使用ProgressBar类的进度条。

只需要这样做:

progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal);

我需要根据输入值更改那个的颜色,像这样:

int color = "red in RGB value".progressBar.setColor(color)

因为进度条是可定制的,所以我不能使用XML布局

14个回答

64
这将会帮助很多,无需进行太多编程 :)
ProgressBar spinner = new android.widget.ProgressBar(
            context,
            null,
            android.R.attr.progressBarStyle);

spinner.getIndeterminateDrawable().setColorFilter(0xFFFF0000,android.graphics.PorterDuff.Mode.MULTIPLY);

7
请注意,这会更改背景和前景颜色,并且如果使用确定性进度条,则需要将 getIndeterminateDrawable() 更改为 getProgressDrawable() - Jake Lee
3
有没有一种方法可以只更改前景颜色而不改变背景颜色? - Prakash
setColorFilter已经过时。 - Nouman Ch

53

更新

在较新的 Android 版本(21 及以上),您可以通过使用 setProgressTintList 方法以编程方式更改进度条的颜色。

要将其设置为红色,请使用:

//bar is a ProgressBar
bar.setProgressTintList(ColorStateList.valueOf(Color.RED));

11
根据您使用ProgressBar的方式,您可能需要调用setSecondaryProgressTintList和/或setIndeterminateTintList - Cristan
运行完美,比其他答案好得多(只需要一行代码)! - Jorn Rigter

48
在需要将背景和进度条涂上不同颜色的情况下,可以使用以下代码:

progress_drawable.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 android:shape="rectangle" >
            <solid android:color="@color/white" />
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <solid android:color="@color/green" />
            </shape>
        </clip>
    </item>
</layer-list>

可以通过程序将它的图层列表项分解并单独着色:

LayerDrawable progressBarDrawable = (LayerDrawable) progressBar.getProgressDrawable();
Drawable backgroundDrawable = progressBarDrawable.getDrawable(0);
Drawable progressDrawable = progressBarDrawable.getDrawable(1);

backgroundDrawable.setColorFilter(ContextCompat.getColor(this.getContext(), R.color.white), PorterDuff.Mode.SRC_IN);
progressDrawable.setColorFilter(ContextCompat.getColor(this.getContext(), R.color.red), PorterDuff.Mode.SRC_IN);

4
我使用了这个解决方案,但是使用DrawableCompat.setTint()替代setColorFilter(),它运行得很好。这是我找到的唯一方法,使背景颜色不会改变。 - Franco
1
@Franco setTint API 21+,请注意。在我的测试中,.setColorFilter似乎适用于16+。 - mikemike396
1
唯一有效且不会使背景变色的方法!! - Matan Dahan
这正是我过去几个小时一直在寻找的!非常感谢!我不知道LayerDrawable的存在! - MedievalCoder

20

我在这里找到了一些帮助,但是现在无法记住链接,所以我发布了完整的解决方案,它非常适合我的需求:

    // Draw a simple progressBar from xml
    progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal);

    // Convert the color (Decimal value) to HEX value: (e.g: #4b96a0)
    String color = colorDecToHex(75, 150, 160);

    // Define a shape with rounded corners
    final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 };
    ShapeDrawable pgDrawable = new ShapeDrawable(new RoundRectShape(roundedCorners,     null, null));

    // Sets the progressBar color
    pgDrawable.getPaint().setColor(Color.parseColor(color));

    // Adds the drawable to your progressBar
    ClipDrawable progress = new ClipDrawable(pgDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);
    progressBar.setProgressDrawable(progress);

    // Sets a background to have the 3D effect
    progressBar.setBackgroundDrawable(Utils.getActivity().getResources()
            .getDrawable(android.R.drawable.progress_horizontal));

    // Adds your progressBar to your layout
    contentLayout.addView(progressBar);

下面是将十进制颜色值转换为十六进制的代码:

public static String colorDecToHex(int p_red, int p_green, int p_blue)
{
    String red = Integer.toHexString(p_red);
    String green = Integer.toHexString(p_green);
    String blue = Integer.toHexString(p_blue);

    if (red.length() == 1)
    {
        red = "0" + red;
    }
    if (green.length() == 1)
    {
        green = "0" + green;
    }
    if (blue.length() == 1)
    {
        blue = "0" + blue;
    }

    String colorHex = "#" + red + green + blue;
    return colorHex;
}

我认为最后的方法不是很优雅,但它能够很好地工作。

希望这也能有所帮助,在进度条上浪费了太多时间。


几乎可以工作,但如果您更改进度条的高度,则背景可绘制对象将太高。 - kenyee

16

使用AppCompat可以解决我的问题:

DrawableCompat.setTint(progressBar.getProgressDrawable(), tintColor);

15

如果您想以编程的方式更改进度条的颜色,请复制并粘贴此代码,它可以百分之百地工作。

 mainProgressBar.getIndeterminateDrawable().setColorFilter(Color.GREEN, PorterDuff.Mode.MULTIPLY);   

15

可以通过设置进度条drawable的颜色过滤器来对进度条进行着色:

Drawable drawable = progressBar.getProgressDrawable();
drawable.setColorFilter(new LightingColorFilter(0xFF000000, customColorInt));

1
这就是我尝试过的方法。 然而,使用这种方法,颜色有点奇怪...实际上,如果我只想要颜色:RGB = #5ea618,带有深灰色背景颜色,我该怎么办?因为例如,如果我正在执行: new LightingColorFilter(0xFF000000, 0xFF5ea618)); 进度条的颜色是绿色的,但我看不到它在移动。 - hico
如果您想要完全控制,您应该自己创建进度条的图形。 - Moritz
1
同时着色背景和前景。 - desgraci
"Drawable.SetColorFilter(Color, PorterDuff.Mode)"已经过时,被标记为“deprecated”。 - Luca Ziegler

10

Kotlin 2021:

Kotlin 2021:
progressBar.indeterminateTintList = ColorStateList.valueOf(Color.WHITE)

您也可以使用 getColor() 方法传递一个资源。

如果不是不定的话,在您的情况下可能需要使用这两个:

setSecondaryProgressTintList

setProgressTintList

8

progressbar.setIndeterminateTintList(ColorStateList.valueOf(Color.RED));

只有在API 21及以上版本才有效。


3

我已经在 xml 中通过 drawable 给出了 默认颜色

我已经通过程序更改了它。

activity_splasg.xml:

<ProgressBar
       android:id="@+id/splashProgressBar"
       android:progressDrawable="@drawable/splash_progress_drawable"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:max="100"
       android:progress="50"
       style="?android:attr/progressBarStyleHorizontal"
       android:layout_alignParentBottom="true" />

splash_progress_drawable.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>
            <solid
                android:color="@android:color/transparent" />
        </shape>
    </item>

    <item
        android:id="@android:id/progress">
        <clip>
            <shape>
                <solid
                    android:color="#e5c771" />
            </shape>
        </clip>
    </item>

</layer-list>

现在,如何通过程序更改ProgressDrawable颜色。
ProgressBar splashProgressBar = (ProgressBar)findViewById(R.id.splashProgressBar);

Drawable bgDrawable = splashProgressBar.getProgressDrawable();
bgDrawable.setColorFilter(Color.BLUE, android.graphics.PorterDuff.Mode.MULTIPLY);
splashProgressBar.setProgressDrawable(bgDrawable);

希望这能帮到你。

4
不,程序化解决方案将会渲染背景和前景颜色... - Henrique de Sousa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接