Cómo cambiar el color del indicador de progreso de ProgressBar en Android

178

He configurado Horizontal ProgressBar.

Me gustaría cambiar el color del progreso a amarillo.

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

El problema es que el color del progreso es diferente en diferentes dispositivos. Entonces, quiero que arregle el color del progreso.

Nishant Shah
fuente
las respuestas anteriores cambian todo el color de fondo y es ambiguo que cambie la altura de la barra de progreso al máximo, lo que no puede cambiar en xml. Una mejor manera de cambiar solo el estado de la barra de progreso es que cuánto se completa es 20% de color rojo, 50% de color amarillo 70% y por encima del color verde. puedes hacerlo programáticamente en java. comparte tu respuesta si tienes alguna otra solución.
Mubashar

Respuestas:

365

Copié esto de una de mis aplicaciones, por lo que es probable que haya algunos atributos adicionales, pero debería darle la idea. Esto es del diseño que tiene la barra de progreso:

<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" />

Luego cree un nuevo dibujo con algo similar a lo siguiente (en este caso 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>

Puede cambiar los colores según sea necesario, esto le dará una barra de progreso verde.

Ryan
fuente
Y también
elimino
2
Por favor, ayúdame. Intento crear greenprogress.xml copiando su código, pero el Android Studio 0.4.6 marca <layer-list> como y el error "Element-list debe ser declarado" ¿qué debo hacer?
UmAnusorn
1
¿Es posible cambiar el color dinámicamente?
asíncrono
¿Se puede cambiar el color dependiendo del valor de progreso actual definido en la barra real?
Jonathan
@Ryan Sería de gran ayuda para explicar lo que android:id="@android:id/progress", android:id="@android:id/background"y android:id="@android:id/secondaryProgress"representamos.
RustamG
103

Una solución más simple:

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>
Nitin Saxena
fuente
1
here @ color / disabled es un color personalizado
Nitin Saxena
2
O <solid android: color = "@ android: color / black" />, o incluso <solid android: color = "# ff33b5e5" />
superarts.org
2
Esto es suficiente android: indeterminateTint = "@ color / white" para la palanca API 21 y superior
Ghanshyam Nayma
53

Solo crea un estilo en values/styles.xml.

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

Luego establece este estilo como tu ProgressBartema.

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

y no importa que tu barra de progreso sea horizontal o circular. Eso es todo.

Ali Zeynali
fuente
1
Wow, la solución más simple, funciona para mí. Me preguntaba por qué esta respuesta tiene tantos votos.
Pavel Shorokhov
38

Si solo desea cambiar el color de la barra de progreso, simplemente puede usar un filtro de color en el método onCreate () de su Actividad:

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);

Idea de aquí .

Solo necesita hacer esto para las versiones previas a la piruleta. En Lollipop puedes usar el atributo de estilo colorAccent.

amfcosta
fuente
Para SeekBarque es lo mismo, sólo tiene que añadir a la API 16: seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);. Esto cambiará el color de ese pulgar redondo.
Sufian
1
Al llamar setColorFilter()directamente a un dibujable se aplicará el color en todas partes. Puesto que esto es lo que no necesito, me acaba de llamar mutate()a la Drawable(es decir, comoseekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Sufian
3
He visto esta solución en otro lugar, pero todo lo que hace (probar en un dispositivo Gingerbread) es cambiar la barra de progreso completa en un solo color, lo que hace imposible ver el progreso real
Neil C. Obremski
@ NeilC.Obremski sí, tienes razón. Puede ser específico de ROM, o tal vez específico de versión. Tuve que eliminarlo por completo. Esperemos que esto se transfiera a versiones anteriores de Android pronto (a través de support lib).
Sufian
25

para API nivel 21 o superior solo use

android:progressBackgroundTint="@color/yourBackgroundColor"
android:progressTint="@color/yourColor"
Mohammad Mousavi
fuente
6

Hay 3 formas de resolver esta pregunta:

  1. Cómo ajustar el color de la barra de progreso de forma declarativa
  2. Cómo ajustar el color de la barra de progreso mediante programación, pero elegir el color de varios colores predeterminados declarados antes del tiempo de compilación
  3. Cómo ajustar el color de la barra de progreso mediante programación y también crear el color mediante programación.

En particular, hay mucha confusión en torno al # 2 y # 3, como se ve en los comentarios a la respuesta de amfcosta. Esa respuesta arrojará resultados de color impredecibles en cualquier momento que desee establecer la barra de progreso en cualquier cosa, excepto los colores primarios, ya que solo modifica el color de fondo, y el área de "clip" de la barra de progreso real seguirá siendo una superposición amarilla con opacidad reducida. Por ejemplo, el uso de ese método para establecer el fondo en púrpura oscuro dará como resultado un color de "clip" de la barra de progreso de un color rosado loco resultante de la mezcla de púrpura oscuro y amarillo a través de alfa reducido.

De todos modos, Ryan responde # 1 perfectamente y Štarke responde la mayor parte de # 3, pero para aquellos que buscan una solución completa para # 2 y # 3:


Cómo ajustar el color de la barra de progreso mediante programación, pero elegir el color de un color predeterminado declarado en XML

res / drawable / my_progressbar.xml :

Cree este archivo pero cambie los colores en my_progress y my_secondsProgress:

(NOTA: Esta es solo una copia del archivo XML real que define la barra de progreso del SDK de Android predeterminado, pero he cambiado los ID y los colores. El original se llama progress_horizontal)

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

En tu 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)

Cómo ajustar el color de la barra de progreso mediante programación y también crear el color mediante programación

EDITAR: encontré el tiempo para resolver esto correctamente. Mi respuesta anterior dejó esto un poco ambiguo.

Un ProgressBar se compone como 3 Drawables en un LayerDrawable.

  1. La capa 1 es el fondo
  2. La capa 2 es el color de progreso secundario
  3. La capa 3 es el color principal de la barra de progreso

En el siguiente ejemplo, cambiaré el color de la barra de progreso principal a cian.

//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);

Ese ejemplo lo configuró en un color sólido. Puede establecerlo en un color degradado reemplazando

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

con

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

Salud.

-Lanza

lanza.dolan
fuente
¿Qué es viewUtils en viewUtils.convertDpToPixel (5);
Nikos Hidalgo
1
Hola @NikosHidalgo: puedes ver un método casi idéntico aquí: stackoverflow.com/questions/12849366/… . La única diferencia es que construyo mi ViewUtilscon una referencia a Context, por lo que no necesito pasar un Contextal llamarconvertDpToPixel()
lance.dolan
¡Gracias por su pronta respuesta, especialmente en una respuesta que se publicó hace mucho tiempo!
Nikos Hidalgo
Jaja, realmente tuve que estirar mi cerebro para recordar: p
lance.dolan
4

Si está en el nivel de API 21 o superior, puede usar estos atributos XML:

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

La solución más simple que descubrí es algo como esto:

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

Ponga lo anterior en el styles.xmlarchivo debajo de la res > valuescarpeta.

NOTA: Si usa cualquier otro color de acento, entonces las soluciones anteriores deberían ser buenas.

API 21 o superior

Sazid
fuente
Esta es la mejor solución. 100% relacionado con la pregunta formulada. muy simple
Pir Fahim Shah
3
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.getDrawable(2).setColorFilter(color,PorterDuff.Mode.SRC_IN);
usuario3135773
fuente
1
Intenta agregar una pequeña explicación a tu respuesta. Se desaconsejan las respuestas de solo código.
Alexei
Me encantaría obtener una explicación detrás del índice 2 en getDrawable, pero al menos esta fue la única solución que funcionó para mí, ¡así que gracias!
Nikos Hidalgo
2

Para cualquiera que busque cómo hacerlo programáticamente:

    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);

Establecer identificadores en elementos dibujables es crucial y se encarga de preservar los límites y la barra de estado de progreso real

Štarke
fuente
1

Ustedes realmente me están dando dolor de cabeza. Lo que puede hacer es hacer que su lista de capas se pueda dibujar a través de xml primero (es decir, un fondo como la primera capa, un dibujo que represente el progreso secundario como la segunda capa y otro dibujable que represente el progreso primario como la última capa), luego cambie el color en el código haciendo lo siguiente:

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);
    }
}

Este método le dará la mejor flexibilidad para que la medición de su dibujo original se declare en el xml, SIN MODIFICAR SU ESTRUCTURA DESPUÉS, especialmente si necesita tener la carpeta de la pantalla del archivo xml específica, luego solo modifique SOLO EL COLOR a través de código. Sin volver a crear una instancia de un nuevo ShapeDrawable desde cero.

Pier Betos
fuente
1

El color de ProgressBar se puede cambiar de la siguiente manera:

/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);
}
Milan Hlinák
fuente
1

Cree un recurso dibujable que fondo necesita, en mi caso lo llamé 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>

Luego use este fondo personalizado como

 <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" />

Funciona bien para mi

Md Juyel Rana
fuente
0

En 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
    }
Soumen Das
fuente
0

Con la Biblioteca de componentes de material puede usar el ProgressIndicatorcon el app:indicatorColoratributo para cambiar el color:

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

ingrese la descripción de la imagen aquí

Nota : requiere al menos la versión1.3.0-alpha01 .

Con el ProgressBarpuede anular el color usando:

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

con:

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

ingrese la descripción de la imagen aquí

Gabriele Mariotti
fuente
0

Si desea establecer el color de progreso primario y secundario en la barra de progreso horizontal mediante programación en Android, use el fragmento a continuación

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));
Rahul Kamble
fuente