如何在Android中更改进度条的进度颜色

598

我正在使用Android应用程序中的水平进度条,并且想要更改其进度颜色(默认为黄色)。如何在代码中完成此操作(不使用XML)?


你尝试过使用MyProgressBar.setProgressDrawable(Drawable d)方法指定一个具有所需颜色的位图吗?http://developer.android.com/reference/android/widget/ProgressBar.html#setProgressDrawable(android.graphics.drawable.Drawable) http://developer.android.com/reference/android/graphics/drawable/Drawable.html - fupsduck
2
是的,我已经尝试过了,但它并没有起作用。它会设置整个进度条视图的背景颜色,而不是仅设置进度条本身的背景颜色。谢谢。 - WhiteTigerK
75
android:indeterminateTint="@android:color/white" 只在 API >=21 版本及以上有效。 - Madeyedexter
1
当您使用非确定性时,android:progressTint="@android:color/white" - Kamil
42个回答

543

虽然这不是编程方法,但我认为它仍然可以帮助很多人。
我尝试了很多方法,最有效的方法是将以下行添加到我的.xml文件中的进度条:


我尝试了很多方法,最有效的方法是将以下行添加到我的.xml文件中的进度条:
            android:indeterminate="true"
            android:indeterminateTintMode="src_atop"
            android:indeterminateTint="@color/secondary"

最终,这段代码为我解决了问题:

<ProgressBar
            android:id="@+id/progressBar"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:layout_marginTop="50dp"
            android:layout_marginBottom="50dp"
            android:visibility="visible"
            android:indeterminate="true"
            android:indeterminateTintMode="src_atop"
            android:indeterminateTint="@color/secondary">

这个解决方案适用于API 21+


我是否需要为API 21+和API <= 20制作自定义资源文件?还是这些属性在API <= 20中被忽略了? - prom85
1
@shriduttkothari 怎么可能是最好的?... 它只有21+。 - user25
6
随着Android逐渐远离4.x版本,最佳答案是什么? - Tom
1
这是一个很好的答案,只需要在改变颜色的方法中使用@TargetApi注释,这样当API小于21时就不会崩溃。 - Hanako
1
这是一个用于加载目的的通用对话框进度显示的最佳答案。 - Tarique Anowar
显示剩余2条评论

540

对于水平进度条,您也可以像这样使用ColorFilter

progressBar.getProgressDrawable().setColorFilter(
    Color.RED, android.graphics.PorterDuff.Mode.SRC_IN);

使用颜色过滤器的红色进度条

注意:这将修改应用程序中所有进度条的外观。如果只想修改特定的一个进度条,请执行以下操作:

Drawable progressDrawable = progressBar.getProgressDrawable().mutate();
progressDrawable.setColorFilter(Color.RED, android.graphics.PorterDuff.Mode.SRC_IN);
progressBar.setProgressDrawable(progressDrawable);

如果进度条是不确定的,则使用getIndeterminateDrawable()而不是getProgressDrawable()

自 Lollipop(API 21)以来,您可以设置进度着色:

progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));

使用进度色调的红色进度条


7
我想使用这个答案,因为它对我来说似乎是最简单的,但我的进度条完全是红色的,与进度值无关。你确定要使用这种模式吗? - L. G.
36
我跟 @resus 有同样的问题,进度条完全是红色且没有任何进展。但我解决了这个问题,通过将 Mode.SRC_IN 改为 Mode.MULTIPLY。 - Derzu
43
如果您正在使用不确定进度,请不要忘记为 getIndeterminateDrawable 做同样的操作。 - Thommy
9
如何不改变背景颜色?我只想改变进度条的颜色。 - kangear
3
您可以使用Color.parseColor("#12ddfe")代替Color.RED。 - Torben Kohlmeier
显示剩余11条评论

316

很抱歉这不是答案,但是是什么推动了从代码中设置的要求?.setProgressDrawable如果定义正确应该可以正常工作。

<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="@color/progress_start"
                android:endColor="@color/progress_end"
                android:angle="270" 
            />
        </shape>
    </clip>
</item>

</layer-list>

6
原文:The reason is because I'm creating the progress bar dynamically, and setting its color upon user request. Since I usually use code for building my GUI screen and components, I'm not familiar with the attached XML and I don't know what's a layer-list (although I'm guessing that you are building the progress bar based on several layers..).In case I do want to use the XML you've attached - where should I place the it in the project's folder and is there anything more I need to do for creating a progress bar based on the XML settings ?Thanks.翻译:原因是我正在动态创建进度条,并根据用户请求设置其颜色。由于通常使用代码构建GUI屏幕和组件,我不熟悉附加的XML文件,也不知道什么是layer-list(尽管我猜测您正在基于几个层构建进度条..)。如果我确实想要使用您提供的XML文件-我应该将它放在项目文件夹的哪个位置,并且是否还需要做更多的工作以基于XML设置创建进度条?谢谢。 - WhiteTigerK
1
你可以将这个xml文件保存为一个文件并放置在drawable文件夹中(比如说my_progress.xml),然后将其设置为MyProgressBar.setProgressDrawable()中的drawable。如果要更改颜色,你需要更改@color/progress_start和@color/progress_end中的值。它基本上是一个渐变,你可以在里面放入十六进制数。 - Alex Volovoy
3
注意 - 文件是 SDK 中的副本。我已经在这里删除了版权。如果你查看 res/drawable 文件夹,你会看到我所发布的内容 - 颜色被设置为黄色渐变,而不是自定义颜色。 - Alex Volovoy
7
它对我来说没有显示任何颜色变化。请告诉我起作用的颜色。 - Praveen
嗨Alex,你的答案非常好。但是,我试图在运行时更改自定义进度轮的颜色,但是我无法做到。请帮助我解决这个问题..当进度达到100%时,然后改变颜色并开始进度..我从这里下载了代码..https://dev59.com/n3bZa4cB1Zd3GeqPDTzu - harikrishnan
显示剩余6条评论

245

对于我的不确定进度条(spinner),我只需在可绘制对象上设置颜色过滤器即可。这非常有效,只需要一行代码。

以下是将颜色设置为红色的示例:

ProgressBar spinner = new android.widget.ProgressBar(
                context,
                null,
                android.R.attr.progressBarStyle);

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

输入图像描述


17
我最喜欢你的回答了。不过为了让我的工作正常运行,我必须这样做:myProgressBarSpinner.getIndeterminateDrawable().setColorFilter(new LightingColorFilter(0xFF000000, foregroundColorDesired)); - Art Geigel
5
请注意,这样做会修改您应用程序中所有进度条的可绘制对象。要仅对特定进度条执行此操作,请在可绘制对象上调用mutate(),然后设置其颜色过滤器,最后将其设置为您的进度条中的不确定可绘制对象。 - dimsuz
3
注意:使用此功能并想知道为什么颜色看起来与他们输入的十六进制字符串不完全相同的人,这是因为它有一个多重颜色过滤器。将 android.graphics.PorterDuff.Mode.MULTIPLY 更改为 PorterDuff.Mode.SRC_IN,您将获得精确的十六进制颜色。 - micnguyen
我认为他只需要这个答案...... android:indeterminateTint="@android:color/black" - Muhammad Adil
4
我使用了以下代码:progressBar = (ProgressBar) findViewById(R.id.progressBar); progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(this,android.R.color.white), android.graphics.PorterDuff.Mode.MULTIPLY); - ashishdhiman2007

218

这是一个旧问题,但此处未提及使用主题。如果默认主题使用AppCompat,则您定义的colorAccent将成为ProgressBar的颜色。

更改colorAccent也将更改您的ProgressBar的颜色,但这些更改也会反映在多个位置。因此,如果您只想针对特定的ProgressBar设置不同的颜色,可以通过将主题应用于该ProgressBar来实现:

  • 扩展您的默认主题并覆盖colorAccent

<style name="AppTheme.WhiteAccent">
    <item name="colorAccent">@color/white</item> <!-- Whatever color you want-->
</style>
  • ProgressBar 中添加 android:theme 属性:

  • android:theme="@style/AppTheme.WhiteAccent"
    

    因此,它将看起来像这样:

    <ProgressBar
            android:id="@+id/loading"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:padding="10dp"
            android:theme="@style/AppTheme.WhiteAccent" />
    

    所以你只需要更改你特定的ProgressBarcolorAccent

    注意:使用style将不起作用。您只需要使用android:theme。 您可以在此处找到有关主题的更多用法:https://plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH


    20
    终于!谢谢,似乎没有太多开发人员使用AppCompat,很多用户只投票赞成针对API 21+的解决方案,这样不好,他们应该尽可能支持更多设备/操作系统。 - user25
    1
    太棒了!对我有用,但我必须确保在样式层次结构中有一个parent="@style/Theme.AppCompat",因为我之前有另一个parent,一开始它不起作用。 - Nublodeveloper
    1
    @kirtan403 啊,是的,现在你提到了我明白了,但当我第一次阅读时我没有那样理解。我读得太快了,而且我一直在寻找代码。无论如何,谢谢你,你的答案对我来说是最好的! - Nublodeveloper
    我是否错了,还是这只适用于API 21+? - Kirill Starostin
    谢谢,伙计!这正是我在寻找的。 - bellotas
    显示剩余4条评论

    69

    全部API

    如果使用全部API,只需要在style中创建主题。

    style.xml

    <resources>
    
        //...
    
        <style name="progressBarBlue" parent="@style/Theme.AppCompat">
            <item name="colorAccent">@color/blue</item>
        </style>
    
    </resources>
    

    并且正在使用中

    <ProgressBar
        ...
        android:theme="@style/progressBarBlue" />
    

    API 级别 21 及更高版本

    如果在 API 级别 21 或更高版本中使用,请使用以下代码:

    <ProgressBar
       //...
       android:indeterminate="true"
       android:indeterminateTintMode="src_atop"
       android:indeterminateTint="@color/secondary"/>
    

    1
    不错,我认为style.xml方法是最好的。(不需要20个以上的API) - iamkdblue

    53

    这对我有效,而且较低版本也可用。将此添加到您的styles.xml中。

    <style name="ProgressBarTheme" parent="ThemeOverlay.AppCompat.Light">
    <item name="colorAccent">@color/colorPrimary</item>
    </style>
    

    并在xml中像这样使用它

    <ProgressBar
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:theme="@style/ProgressBarTheme"
       />
    

    1
    我已经在CryptoTweets示例应用程序中实现了这个功能。我发现父主题对于此解决方案的预期工作并不是必需的。parent="ThemeOverlay.AppCompat.Light" - AdamHurwitz
    如果您想给默认进度条着色,最简单的解决方案。谢谢。 - Saul_programa
    @Saul_programa 很高兴知道它对你有帮助。 - Devinder Jhinjer

    41

    这对我很有效:

    <ProgressBar
     android:indeterminateTint="#d60909"
     ... />
    

    14
    仅适用于API级别21及以上。 - Numair

    35

    根据一些建议,您可以指定一个形状和带颜色的 ClipDrawable,然后进行设置。我已经通过程序将其实现。以下是我的做法:

    首先确保导入 drawable 库:

    import android.graphics.drawable.*;

    然后使用类似下面的代码:

    ProgressBar pg = (ProgressBar)row.findViewById(R.id.progress);
    final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 };
    pgDrawable = new ShapeDrawable(new RoundRectShape(roundedCorners, null,null));
    String MyColor = "#FF00FF";
    pgDrawable.getPaint().setColor(Color.parseColor(MyColor));
    ClipDrawable progress = new ClipDrawable(pgDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);
    pg.setProgressDrawable(progress);   
    pg.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal));
    pg.setProgress(45);
    

    1
    我尝试了上面的代码,但是进度条却显示为空。我有什么遗漏吗? - OceanBlue
    你需要在ClipDrawable上调用setLevel方法。它接受0到10000的值。因此,progress.setLevel(2500)将是25%满。 - HappyEngineer
    1
    我已经提交了一个编辑答案,解释了“空”进度条的一个原因 - 以及两种修复方法(包括@HappyEngineer的修复)。 - Richard Le Mesurier
    @RichardLeMesurier 你可以在评论区发布解释和两种方法吗?progress.setLevel(2500)对我无效,显然你的编辑由于某些原因未被接受。谢谢。+1. - ateiob
    @ateiob 我已经写了一个新的答案来解释... - Richard Le Mesurier
    为了替换最后一行中弃用的方法:pg.setBackground(ContextCompat.getDrawable(getActivity(), android.R.drawable.progress_horizontal)); - Gustavo

    31

    如果是未确定状态:

    ((ProgressBar)findViewById(R.id.progressBar))
        .getIndeterminateDrawable()
        .setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
    

    我使用了这个,但它没有动画效果,只有颜色被应用... 我正在使用圆形进度条。 - Manikandan

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