我在我的Android应用程序中使用水平进度条,我想改变它的进度颜色(默认为黄色)。我如何使用代码(而不是XML)做到这一点?


当前回答

因为方法公共无效setColorFilter(@ColorInt int颜色,@NonNull PorterDuff。模式模式)已弃用,我使用这样的形式:

progressBar.indeterminateDrawable.colorFilter =
            PorterDuffColorFilter(ContextCompat.getColor(this, R.color.black), PorterDuff.Mode.SRC_IN)

其他回答

相信我,最简单的解决方法就是把这个粘贴到progressBar中:

android:indeterminateTint="@android:color/white"

所有接口

如果使用所有的API只创建主题的样式

style.xml

<resources>

    //...

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

</resources>

在进行中使用

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

空气污染指数21或以上

如果在API级别21及以上使用,请使用以下代码:

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

水平ProgressBar使用矩形形状绘制背景,ClipDrawable从矩形形状构建的进展(主要和次要)。着色将颜色改变为某种色调。如果你想分别为这三种颜色设置目标颜色,你可以使用ProgressBar.setProgressDrawable(),如下所示:

    LayerDrawable progressBarDrawable = new LayerDrawable(
        new Drawable[]{
                new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
                            new int[]{Color.parseColor("#ff0000ff"),Color.parseColor("#ff0000ff")}),

                new ClipDrawable(
                            new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
                                    new int[]{Color.parseColor("#ff00ff00"),Color.parseColor("#ff00ff00")}),
                            Gravity.START,
                            ClipDrawable.HORIZONTAL),

                new ClipDrawable(
                        new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
                                new int[]{Color.parseColor("#ffff0000"),Color.parseColor("#ffff0000")}),
                        Gravity.START,
                        ClipDrawable.HORIZONTAL)
            });

    progressBarDrawable.setId(0,android.R.id.background);
    progressBarDrawable.setId(1,android.R.id.secondaryProgress);
    progressBarDrawable.setId(2,android.R.id.progress);
    ((ProgressBar)findViewById(R.id.progressBar)).setProgressDrawable(progressBarDrawable);

注意,在初始化LayerDrawable时,可绘制层的顺序很重要。首先绘制的应该是背景。根据我的实验,切换id是行不通的。如果你将填充设置为progressbar,那么这种方法将不起作用。如果你需要填充,那么你可以使用一个容器的进度条,如线性布局。

这个解决方案对我很有效:

<style name="Progressbar.White" parent="AppTheme">
    <item name="colorControlActivated">@color/white</item>
</style>

<ProgressBar
    android:layout_width="@dimen/d_40"
    android:layout_height="@dimen/d_40"
    android:indeterminate="true"
    android:theme="@style/Progressbar.White"/>

对于水平风格的ProgressBar,我使用:

import android.widget.ProgressBar;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.ClipDrawable;
import android.view.Gravity;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;

public void setColours(ProgressBar progressBar,
                        int bgCol1, int bgCol2, 
                        int fg1Col1, int fg1Col2, int value1,
                        int fg2Col1, int fg2Col2, int value2)
  {
    //If solid colours are required for an element, then set
    //that elements Col1 param s the same as its Col2 param
    //(eg fg1Col1 == fg1Col2).

    //fgGradDirection and/or bgGradDirection could be parameters
    //if you require other gradient directions eg LEFT_RIGHT.

    GradientDrawable.Orientation fgGradDirection
        = GradientDrawable.Orientation.TOP_BOTTOM;
    GradientDrawable.Orientation bgGradDirection
        = GradientDrawable.Orientation.TOP_BOTTOM;

    //Background
    GradientDrawable bgGradDrawable = new GradientDrawable(
            bgGradDirection, new int[]{bgCol1, bgCol2});
    bgGradDrawable.setShape(GradientDrawable.RECTANGLE);
    bgGradDrawable.setCornerRadius(5);
    ClipDrawable bgclip = new ClipDrawable(
            bgGradDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);     
    bgclip.setLevel(10000);

    //SecondaryProgress
    GradientDrawable fg2GradDrawable = new GradientDrawable(
            fgGradDirection, new int[]{fg2Col1, fg2Col2});
    fg2GradDrawable.setShape(GradientDrawable.RECTANGLE);
    fg2GradDrawable.setCornerRadius(5);
    ClipDrawable fg2clip = new ClipDrawable(
            fg2GradDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);        

    //Progress
    GradientDrawable fg1GradDrawable = new GradientDrawable(
            fgGradDirection, new int[]{fg1Col1, fg1Col2});
    fg1GradDrawable.setShape(GradientDrawable.RECTANGLE);
    fg1GradDrawable.setCornerRadius(5);
    ClipDrawable fg1clip = new ClipDrawable(
            fg1GradDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);        

    //Setup LayerDrawable and assign to progressBar
    Drawable[] progressDrawables = {bgclip, fg2clip, fg1clip};
    LayerDrawable progressLayerDrawable = new LayerDrawable(progressDrawables);     
    progressLayerDrawable.setId(0, android.R.id.background);
    progressLayerDrawable.setId(1, android.R.id.secondaryProgress);
    progressLayerDrawable.setId(2, android.R.id.progress);

    //Copy the existing ProgressDrawable bounds to the new one.
    Rect bounds = progressBar.getProgressDrawable().getBounds();
    progressBar.setProgressDrawable(progressLayerDrawable);     
    progressBar.getProgressDrawable().setBounds(bounds);

    // setProgress() ignores a change to the same value, so:
    if (value1 == 0)
        progressBar.setProgress(1);
    else
        progressBar.setProgress(0);
    progressBar.setProgress(value1);

    // setSecondaryProgress() ignores a change to the same value, so:
    if (value2 == 0)
        progressBar.setSecondaryProgress(1);
    else
        progressBar.setSecondaryProgress(0);
    progressBar.setSecondaryProgress(value2);

    //now force a redraw
    progressBar.invalidate();
  }

一个调用的例子是:

  setColours(myProgressBar, 
          0xff303030,   //bgCol1  grey 
          0xff909090,   //bgCol2  lighter grey 
          0xff0000FF,   //fg1Col1 blue 
          0xffFFFFFF,   //fg1Col2 white
          50,           //value1
          0xffFF0000,   //fg2Col1 red 
          0xffFFFFFF,   //fg2Col2 white
          75);          //value2

如果您不需要“次要进度”,只需将value2设置为value1。