如何在Android中更改ProgressBar的进度指示器颜色


177

我设置了Horizo​​ntal ProgressBar

我想将进度颜色更改为黄色。

<ProgressBar 
    android:id="@+id/progressbar" 
    android:layout_width="80dip" 
    android:layout_height="20dip"  
    android:focusable="false" 
    style="?android:attr/progressBarStyleHorizontal" />

问题是,进度颜色在不同的设备中是不同的。因此,我希望它可以修复进度颜色。


上面的答案改变了整个背景色,这是矛盾的,它将进度条的高度更改为非常大。这在xml中无法更改。仅更改进度条状态的更好方法是完成20%的红色,50%的黄色,70%的绿色以及绿色。您可以在Java中以编程方式进行操作。如果您有其他解决方案,请分享您的答案。
Mubashar

Answers:


364

我从我的一个应用程序中复制了此文件,因此可能会有一些额外的属性,但是应该可以给您带来启发。这来自具有进度条的布局:

<ProgressBar
    android:id="@+id/ProgressBar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:indeterminate="false"
    android:maxHeight="10dip"
    android:minHeight="10dip"
    android:progress="50"
    android:progressDrawable="@drawable/greenprogress" />

然后创建一个类似于以下内容的新drawable(在这种情况下greenprogress.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:angle="270"
                android:centerColor="#ff5a5d5a"
                android:centerY="0.75"
                android:endColor="#ff747674"
                android:startColor="#ff9d9e9d" />
        </shape>
    </item>

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

</layer-list>

您可以根据需要更改颜色,这将为您提供绿色的进度条。


而且我也删除了这个android:indeterminate =“ false”
Nishant Shah

2
请帮我。我尝试通过复制代码来创建greenprogress.xml,但是Android Studio 0.4.6将<layer-list>标记为,并且出现错误“必须声明元素列表”,我该怎么办?
UmAnusorn 2014年

1
是否可以动态更改颜色?
2014年

是否可以根据实际栏中定义的当前进度值更改颜色?
乔纳森(Jonathan)

@Ryan这将有助于解释什么android:id="@android:id/progress"android:id="@android:id/background"android:id="@android:id/secondaryProgress"代表。
RustamG '17

103

一个更简单的解决方案:

progess_drawable_blue

<?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="@color/disabled" />
    </shape>
</item>

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

</layer-list>

1
@ color / disabled是自定义颜色
Nitin Saxena 2013年

2
或<solid android:color =“ @ android:color / black” />,甚至<solid android:color =“#ff33b5e5” />
superarts.org 2014年

2
对于API操纵杆21及更高版本,这已经足够android:indeterminateTint =“ @ color / white”
Ghanshyam Nayma,

52

只需在中创建样式即可values/styles.xml

<style name="ProgressBarStyle">
    <item name="colorAccent">@color/greenLight</item>
</style>

然后将此样式设置为ProgressBar主题。

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

而且进度条是水平还是圆形都没关系。就这样。


1
哇,最简单的解决方案对我有用。我想知道为什么这个答案有这么多票。
帕维尔·肖罗霍夫

38

如果您只想更改进度条的颜色,则只需在Activity的onCreate()方法中使用滤色器:

ProgressBar progressbar = (ProgressBar) findViewById(R.id.progressbar);
int color = 0xFF00FF00;
progressbar.getIndeterminateDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
progressbar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);

这里的想法。

您只需要对棒棒糖之前的版本执行此操作。在棒棒糖上,您可以使用colorAccent样式属性。


因为SeekBar相同,只需为API 16:添加seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);。这将改变圆形拇指的颜色。
Sufian

1
setColorFilter()直接调用可绘制对象将在各处应用颜色。由于这是我不需要的,所以我只是打电话mutate()Drawable(即seekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Sufian

3
我在其他地方看到过该解决方案,但它所做的一切(在Gingerbread设备上进行测试)是将整个进度条变成一种颜色,从而无法看到实际的进度
Neil C. Obremski

@ NeilC.Obremski是的,您是对的。它可能是ROM特定的,或者是版本特定的。我不得不将其完全删除。希望我们能够尽快将其移植回旧版Android(通过支持lib)。
Sufian


6

有3种方法可以解决此问题:

  1. 如何以声明方式调整进度条颜色
  2. 如何以编程方式调整进度条颜色,但是要从编译前声明的各种预定颜色中选择颜色
  3. 如何以编程方式调整进度条颜色,以及如何以编程方式创建颜色。

特别是在#2和#3周围有很多困惑,如对amfcosta答案的评论所示。只要您想将进度栏设置为除原色以外的任何时间,该答案都将产生无法预测的颜色结果,因为它仅修改背景颜色,并且实际的进度条“剪辑”区域仍将是具有降低不透明度的黄色覆盖。例如,使用该方法将背景设置为深紫色将导致进度条“剪辑”颜色有些疯狂的粉红色,这是由于暗紫色和黄色通过减少的alpha混合而产生的。

因此,无论如何,Ryan完美地回答了#1,而Štarke回答了第3个问题的大部分答案,但是对于那些寻求针对#2和#3的完整解决方案的人来说:


如何以编程方式调整进度条颜色,但从XML声明的预定颜色中选择颜色

res / drawable / my_progressbar.xml

创建此文件,但更改my_progress和my_secondsProgress中的颜色:

(注意:这只是定义默认android SDK ProgressBar的实际XML文件的副本,但我更改了ID和颜色。原始名称为progress_horizo​​ntal)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@+id/my_progress_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="@+id/my_secondaryProgress">
    <clip>
        <shape>
            <corners android:radius="5dip" />
            <gradient
                android:startColor="#80ff171d"
                android:centerColor="#80ff1315"
                android:centerY="0.75"
                android:endColor="#a0ff0208"
                android:angle="270"
                />
        </shape>
    </clip>
</item>

<item android:id="@+id/my_progress">
    <clip>
        <shape>
            <corners android:radius="5dip" />
            <gradient
                android:startColor="#7d2afdff"
                android:centerColor="#ff2afdff"
                android:centerY="0.75"
                android:endColor="#ff22b9ba"
                android:angle="270"
                />
        </shape>
    </clip>
</item>

在您的Java中

final Drawable drawable;
int sdk = android.os.Build.VERSION.SDK_INT;
    if(sdk < 16) {
        drawable =  ctx.getResources().getDrawable(R.drawable.my_progressbar);
    } else {
        drawable = ContextCompat.getDrawable(ctx, R.drawable.my_progressbar);
    }
progressBar.setProgressDrawable(drawable)

如何以编程方式调整进度条颜色,以及如何以编程方式创建颜色

编辑:我发现时间来解决此问题。我以前的回答使这一点有些含糊。

ProgressBar由LayerDrawable中的3个Drawable组成。

  1. 第1层是背景
  2. 第2层是次要进度色
  3. 第3层是主要的进度条颜色

在下面的示例中,我将主进度条的颜色更改为青色。

//Create new ClipDrawable to replace the old one
float pxCornerRadius = viewUtils.convertDpToPixel(5);
final float[] roundedCorners = new float[] { pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius, pxCornerRadius };
ShapeDrawable shpDrawable = new ShapeDrawable(new RoundRectShape(roundedCorners, null, null));
shpDrawable.getPaint().setColor(Color.CYAN);
final ClipDrawable newProgressClip = new ClipDrawable(shpDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);

//Replace the existing ClipDrawable with this new one
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.setDrawableByLayerId(R.id.my_progress, newProgressClip);

该示例将其设置为纯色。您可以通过替换将其设置为渐变颜色

shpDrawable.getPaint().setColor(Color.CYAN);

Shader shader = new LinearGradient(0, 0, 0, progressBar.getHeight(), Color.WHITE, Color.BLACK, Shader.TileMode.CLAMP);
shpDrawable.getPaint().setShader(shader);

干杯。

-槊


viewUtils.convertDpToPixel(5)中的viewUtils是什么?
Nikos Hidalgo,

1
@NikosHidalgo,您好:您可以在这里看到几乎相同的方法:stackoverflow.com/questions/12849366/…。唯一的不同是,我ViewUtils使用对的引用构造了my Context,因此Context调用时不需要传递aconvertDpToPixel()
lance.dolan

感谢您的及时答复,特别是对于很久以前发布的答案!
Nikos Hidalgo,

哈哈,我真的不得不
竭尽全力

4

如果您处于API级别21或更高级别,则可以使用以下XML属性:

<!-- For indeterminate progress bar -->
android:indeterminateTint="@color/white"
<!-- For normal progress bar -->
android:progressTint="@color/white"

3

我发现的最简单的解决方案是这样的:

<item name="colorAccent">@color/white_or_any_color</item>

将以上内容放入styles.xml文件res > values夹下的文件中。

注意:如果您使用任何其他强调颜色,则以前的解决方案应该很好。

API 21或更高版本


这是最好的解决方案。100%与询问的问题有关。非常简单
Pir Fahim Shah,

3
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.getDrawable(2).setColorFilter(color,PorterDuff.Mode.SRC_IN);

1
尝试为您的答案添加一些解释。不鼓励仅使用代码的答案。
Alexei

我很想在getDrawable的索引2后面得到一个解释,但是至少这是唯一对我有用的解决方案,所以谢谢!
Nikos Hidalgo

2

对于寻找如何以编程方式进行操作的任何人:

    Drawable bckgrndDr = new ColorDrawable(Color.RED);
    Drawable secProgressDr = new ColorDrawable(Color.GRAY);
    Drawable progressDr = new ScaleDrawable(new ColorDrawable(Color.BLUE), Gravity.LEFT, 1, -1);
    LayerDrawable resultDr = new LayerDrawable(new Drawable[] { bckgrndDr, secProgressDr, progressDr });
    //setting ids is important
    resultDr.setId(0, android.R.id.background);
    resultDr.setId(1, android.R.id.secondaryProgress);
    resultDr.setId(2, android.R.id.progress);

将ID设置为可绘制对象至关重要,并且要注意保留边界和进度条的实际状态


1

你们真让我头疼。您可以做的是首先通过xml使图层列表可绘制(表示背景为第一层,将可绘制状态表示为第二进度的可绘制对象作为第二层,另一个可绘制对象将主要进度表示为最后的图层),然后进行更改通过执行以下操作在代码上显示颜色:

public void setPrimaryProgressColor(int colorInstance) {
      if (progressBar.getProgressDrawable() instanceof LayerDrawable) {
        Log.d(mLogTag, "Drawable is a layer drawable");
        LayerDrawable layered = (LayerDrawable) progressBar.getProgressDrawable();
        Drawable circleDrawableExample = layered.getDrawable(<whichever is your index of android.R.id.progress>);
        circleDrawableExample.setColorFilter(colorInstance, PorterDuff.Mode.SRC_IN);
        progressBar.setProgressDrawable(layered);
    } else {
        Log.d(mLogTag, "Fallback in case it's not a LayerDrawable");
        progressBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
    }
}

此方法将为您提供最大的灵活性,使您可以在xml上声明原始可绘制对象的尺寸,而无需对其结构进行任何修改,特别是如果您需要特定于xml文件的screen文件夹,然后仅通过码。无需从头开始重新实例化新的ShapeDrawable。


1

可更改ProgressBar颜色,如下所示:

/res/values/colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorAccent">#FF4081</color>
</resources>

/res/values/styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorAccent">@color/colorAccent</item>
</style> 

onCreate:

progressBar = (ProgressBar) findViewById(R.id.progressBar);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    Drawable drawable = progressBar.getIndeterminateDrawable().mutate();
    drawable.setColorFilter(ContextCompat.getColor(this, R.color.colorAccent), PorterDuff.Mode.SRC_IN);
    progressBar.setIndeterminateDrawable(drawable);
}

1

在需要的背景上创建可绘制资源,在我的情况下,我将其命名为bg_custom_progressbar.xml

<?xml version="1.0" encoding="utf-8"?>

<item>
    <shape android:shape="rectangle" >
        <corners android:radius="5dp"/>

        <gradient
            android:angle="180"
            android:endColor="#DADFD6"
            android:startColor="#AEB9A3" />
    </shape>
</item>
<item>
    <clip>
        <shape android:shape="rectangle" >
            <corners android:radius="5dp" />

            <gradient
                android:angle="180"
                android:endColor="#44CF4A"
                android:startColor="#2BB930" />
        </shape>
    </clip>
</item>
<item>
    <clip>
        <shape android:shape="rectangle" >
            <corners android:radius="5dp" />

            <gradient
                android:angle="180"
                android:endColor="#44CF4A"
                android:startColor="#2BB930" />
        </shape>
    </clip>
</item>

然后像这样使用自定义背景

 <ProgressBar
                android:id="@+id/progressBarBarMenuHome"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="match_parent"
                android:layout_height="20dp"
                android:layout_marginStart="10dp"
                android:layout_marginEnd="10dp"
                android:layout_marginBottom="6dp"
                android:indeterminate="false"
                android:max="100"
                android:minWidth="200dp"
                android:minHeight="50dp"
                android:progress="10"
                android:progressDrawable="@drawable/bg_custom_progressbar" />

它对我来说很好


0

在xml中:

<ProgressBar
                    android:id="@+id/progressBar"
                    style="?android:attr/progressBarStyleInverse"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    android:layout_margin="@dimen/dimen_10dp"


                 android:indeterminateTint="@{viewModel.getComplainStatusUpdate(position)}"
                    android:indeterminate="true"
                    android:indeterminateOnly="false"
                    android:max="100"
                    android:clickable="false"
                    android:indeterminateDrawable="@drawable/round_progress"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

ViewModel:

fun getComplainStatusUpdate(position: Int):Int{

                val list = myAllComplainList!!.getValue()
                if (list!!.get(position).complainStatus.equals("P")) {
                  //  progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
                   // progressBar.setBackgroundResource(R.drawable.circle_shape)
                    return Color.RED
                } else if (list!!.get(position).complainStatus.equals("I")) {

                    return Color.GREEN
                } else {

                    return Color.GREEN
                }


return Color.CYAN
    }

0

在Material Components Library中,您可以将ProgressIndicatorwith app:indicatorColor属性用于更改颜色:

  <com.google.android.material.progressindicator.ProgressIndicator
      style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Determinate"
      app:indicatorColor="@color/..."
      app:indicatorWidth="..."
      app:trackColor="@color/..."
      />

在此处输入图片说明

注意:它至少需要版本1.3.0-alpha01

使用,ProgressBar您可以使用以下方法覆盖颜色:

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

与:

<style name="CustomProgressBarTheme">
    <item name="colorAccent">@color/primaryDarkColor</item>
</style>

在此处输入图片说明


0

如果您想在Android中以编程方式将主要和次要进度颜色设置为水平进度条,请使用以下代码段

int[][] states = new int[][] {
                        new int[] {-android.R.attr.state_checked},
                        new int[] {android.R.attr.state_checked},
                };

                int[] secondaryColor = new int[] {
                        context.getResources().getColor(R.color.graph_line_one),
                        Color.RED,
                };

                int[] primaryColor = new int[] {
                        context.getResources().getColor(R.color.middle_progress),
                        Color.BLUE,
                };
                progressbar.setProgressTintList(new ColorStateList(states, primaryColor));
                progressbar.setSecondaryProgressTintList(new ColorStateList(states, secondaryColor));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.