Cómo cambiar el color de progreso de la barra de progreso en Android

Estoy usando una barra de progreso horizontal en mi aplicación de Android, y quiero cambiar su color de progreso (que es amarillo por defecto). ¿Cómo puedo hacerlo usando code (no XML)?

Lo siento que no es la respuesta, pero ¿qué está impulsando el requisito de configuración de código? Y .setProgressDrawable debería funcionar si se ha definido correctamente

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

Para un ProgressBar horizontal, también puede utilizar un ColorFilter como este:

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

Si progressBar es indeterminado, entonces use getIndeterminateDrawable() lugar de getProgressDrawable() .

Red ProgressBar con filtro de color

Desde Lollipop (API 21) puedes configurar un matiz de progreso:

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

Red ProgressBar usando el tinte del progreso

Para mi barra de progreso indeterminada (hilandero) me acaba de establecer un filtro de color en el dibujable. Funciona muy bien y sólo una línea.

Ejemplo de configuración del color en rojo:

 ProgressBar spinner = new android.widget.ProgressBar( context, null, android.R.attr.progressBarStyle); spinner.getIndeterminateDrawable().setColorFilter(0xFFFF0000, android.graphics.PorterDuff.Mode.MULTIPLY); 

Introduzca aquí la descripción de la imagen

Esto no es programmatically pero pienso que podría ayudar a mucha gente de todos modos! He intentado mucho y la manera más eficiente fue añadir estas líneas a mi ProgressBar en el archivo .xml:

  android:indeterminate="true" android:indeterminateTintMode="src_atop" android:indeterminateTint="@color/secondary" 

Así que al final este código lo hizo por mí:

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

Esta solución funciona para API 21+

Esta es una vieja pregunta, pero usar el tema no se menciona aquí. Si el tema predeterminado utiliza AppCompat , el color de su ProgressBar será colorAccent que haya definido.

Cambiar el colorAccent también cambiará el color de tu ProgressBar , pero los cambios también se reflejan en varios lugares. Por lo tanto, si desea un color diferente sólo para un específico PregressBar puede hacer que mediante la aplicación de tema a que ProgressBar :

  • Extender el tema predeterminado y anular colorAccent

     <style name="AppTheme.WhiteAccent"> <item name="colorAccent">@color/white</item> <!-- Whatever color you want--> </style> 
  • Y en ProgressBar añada el atributo android:theme :

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

Así que se verá algo como esto:

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

Así que sólo está cambiando un colorAccent para su ProgressBar particular.

Nota : El uso del style no funcionará. Necesita usar android:theme solo android:theme . Puedes encontrar más uso del tema aquí: https://plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH

Como por algunas de las sugerencias, puede especificar una forma y clipdrawable con un color, a continuación, establecerlo. Tengo esto trabajando programáticamente. Así es como lo hago

Primero asegúrese de importar la biblioteca dibujable ..

import android.graphics.drawable.*;

A continuación, utilice el código similar al siguiente;

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

Pulse el mismo problema mientras trabaja en la modificación de la apariencia / sensación de la barra de progreso predeterminada. Aquí hay más información que esperamos ayude a la gente 🙂

  • El nombre del archivo xml sólo debe contener caracteres: a-z0-9_. (Es decir, sin capitales!)
  • Para hacer referencia a su "dibujable" es R.drawable.filename
  • Para reemplazar el aspecto predeterminado, utiliza myProgressBar.setProgressDrawable(...) , sin embargo, no necesita referirse a su diseño personalizado como R.drawable.filename , necesita recuperarlo como Drawable :
     Resources res = getResources(); myProgressBar.setProgressDrawable(res.getDrawable(R.drawable.filename); 
  • Usted necesita fijar el estilo antes de fijar el progreso / progreso secundario / máximo (fijarlo después para mí dio lugar a una barra de progreso "vacía")

Si es Indeterminado:

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

Hoy en día en 2016 encontré algunos dispositivos pre-Lollipop no cumplen con la configuración colorAccent , así que mi solución final para todas las API es ahora la siguiente:

 // fixes pre-Lollipop progressBar indeterminateDrawable tinting if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { Drawable wrapDrawable = DrawableCompat.wrap(mProgressBar.getIndeterminateDrawable()); DrawableCompat.setTint(wrapDrawable, ContextCompat.getColor(getContext(), android.R.color.holo_green_light)); mProgressBar.setIndeterminateDrawable(DrawableCompat.unwrap(wrapDrawable)); } else { mProgressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), android.R.color.holo_green_light), PorterDuff.Mode.SRC_IN); } 

Para los puntos de bonificación, no utiliza ningún código obsoleto. ¡Intentalo!

Probablemente hay una cosa que no se ha mencionado en esta respuesta:

Si su tema está heredando de Theme.AppCompat , ProgressBar asumirá el color que definió como "colorAccent" en su tema.

Por lo tanto, utilizando ..

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

.. teñirá el color del ProgressBar @color/custom_color .

Cómo lo hice en ProgressBar horizontal:

  LayerDrawable layerDrawable = (LayerDrawable) progressBar.getProgressDrawable(); Drawable progressDrawable = layerDrawable.findDrawableByLayerId(android.R.id.progress); progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); 
 android:progressTint="#ffffff" 

Una cosa más pequeña, la solución de tema funciona si hereda un tema de base, por lo que para el compacto de la aplicación su tema debe ser:

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

A continuación, establezca esto en el tema de la barra de progreso

 <ProgressBar android:id="@+id/progressCircle_progressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:theme="@style/AppTheme.Custom" android:indeterminate="true"/> 

Para un estilo horizontal ProgressBar utilizo:

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

Una llamada de ejemplo sería:

  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 

Si no necesita el 'progreso secundario', simplemente establezca valor2 en valor1.

Publicado para agregar información sobre la respuesta de PaulieG , ya que ateiob me pidió que explicara algo …

Desafortunadamente cuando propuse una edición a la solución, era hace mucho tiempo, y no puedo recordar todos los detalles.


Puedo decir que hay (o al menos era, en el momento de escribir cuando miré la versión actual del código fuente de Android) un error / problema / optimización en el código ProgressBar que ignora un intento de establecer el progreso a un valor Ya está en.

  • Es decir, si progreso = 45, e intenta establecerlo a 45, el código no hará nada y no volverá a dibujar el progreso .

Después de llamar a ProgressBar.setProgressDrawable() , su barra de progreso estará en blanco (porque ha cambiado la parte drawable).

Esto significa que debe configurar el progreso y volver a dibujarlo. Pero si usted apenas fija el progreso a un valor preservado, no hará nada.

Debe establecerlo primero en 0, luego en el valor "antiguo" de nuevo y la barra se volverá a dibujar.


Así que para resumir:

  • Preservar el "viejo" valor de progreso
  • Actualizar el dibujable / color (hace que la barra en blanco)
  • Restablecer el progreso a 0 (de lo contrario la siguiente línea no hace nada)
  • Restablecer el progreso al valor "antiguo" (fija la barra)
  • invalidar

A continuación se muestra un método que tengo que hace esto – espero que sea útil. No estoy 100% seguro de por qué lo llamé de onResume() – esto podría ser importante o no relacionado:

 protected void onResume() { super.onResume(); progBar = (ProgressBar) findViewById(R.id.progress_base); int oldProgress = progBar.getProgress(); // define new drawable/colour final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 }; ShapeDrawable shape = new ShapeDrawable(new RoundRectShape( roundedCorners, null, null)); String MyColor = "#FF00FF"; shape.getPaint().setColor(Color.parseColor(MyColor)); ClipDrawable clip = new ClipDrawable(shape, Gravity.LEFT, ClipDrawable.HORIZONTAL); progBar.setProgressDrawable(clip); progBar.setBackgroundDrawable(getResources().getDrawable( android.R.drawable.progress_horizontal)); // work around: setProgress() ignores a change to the same value progBar.setProgress(0); progBar.setProgress(oldProgress); progBar.invalidate(); } 

En cuanto a la solución de HappyEngineer, creo que fue una solución similar, para establecer manualmente el "avance" de compensación (no recuerdo exactamente). En cualquier caso, el código anterior debería funcionar para usted.

Lo siento si no puedo recordar todos los detalles – por eso he intentado editar la respuesta. Espero que esto ayude…

Esto funcionó para mí:

 <ProgressBar android:indeterminateTint="#d60909" ... /> 
 ProgressBar bar; private Handler progressBarHandler = new Handler(); GradientDrawable progressGradientDrawable = new GradientDrawable( GradientDrawable.Orientation.LEFT_RIGHT, new int[]{ 0xff1e90ff,0xff006ab6,0xff367ba8}); ClipDrawable progressClipDrawable = new ClipDrawable( progressGradientDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL); Drawable[] progressDrawables = { new ColorDrawable(0xffffffff), progressClipDrawable, progressClipDrawable}; LayerDrawable progressLayerDrawable = new LayerDrawable(progressDrawables); int status = 0; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // TODO Auto-generated method stub setContentView(R.layout.startup); bar = (ProgressBar) findViewById(R.id.start_page_progressBar); bar.setProgress(0); bar.setMax(100); progressLayerDrawable.setId(0, android.R.id.background); progressLayerDrawable.setId(1, android.R.id.secondaryProgress); progressLayerDrawable.setId(2, android.R.id.progress); bar.setProgressDrawable(progressLayerDrawable); } 

Esto me ayudó a establecer un color personalizado a la barra de progreso a través del código. Espero eso ayude

Esta solución funcionó para mí:

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

Aplique este estilo personalizado a la barra de progreso.

 <style name="customProgress" parent="@android:style/Widget.ProgressBar.Small"> <item name="android:indeterminateDrawable">@drawable/progress</item> <item name="android:duration">40</item> <item name="android:animationCache">true</item> <item name="android:drawingCacheQuality">low</item> <item name="android:persistentDrawingCache">animation</item> </style> 

@ Drawable / progress.xml –

 <?xml version="1.0" encoding="utf-8"?> <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/spinner_white" android:pivotX="50%" android:pivotY="50%" /> 

Utilice este tipo de imagen para la barra de progreso. Introduzca aquí la descripción de la imagen

Para obtener un mejor resultado, puede utilizar varias imágenes de progreso. Y no dudes en usar imágenes, ya que la propia Plataforma Android utiliza imágenes para la barra de progreso. El código se extrae de sdk 🙂

Según muhammad-adil sugerido para SDK ver 21 y superior

 android:indeterminateTint="@color/orange" 

En XML funciona para mí, es bastante fácil.

Horizontal ProgressBar utiliza la rectangle shape ClipDrawable para el fondo, ClipDrawable construido de la rectangle shape del rectangle shape para progresos (primario y secundario). El tintado cambia los colores a algo de tinte. Si desea colores de destino para los tres por separado, a continuación, puede utilizar ProgressBar.setProgressDrawable() como sigue:

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

Tenga en cuenta que el orden de las capas LayerDrawable es importante al inicializar LayerDrawable . El primer dibujable debe ser para el fondo. Según mi experimento el cambio de ids no funciona. Si establece el relleno en la barra de progressbar entonces este enfoque no funcionará. Si necesita relleno, puede utilizar un contenedor para la LinearLayout progreso, como un LinearLayout .

Es tan simple usar attr, si se trata de aplicaciones de varios estilos:

Pruebe de esta manera:

Declare abajo el atributo attrs.xml

  <attr name="circularProgressTheme" format="reference"></attr> 

Pegue debajo del código en styles.xml

  <style name="ProgressThemeWhite" parent="ThemeOverlay.AppCompat.Light"> <item name="colorAccent">#FF0000</item> </style> <style name="circularProgressThemeWhite"> <item name="android:theme">@style/ProgressThemeWhite</item> </style> <style name="AppTheme" parent="Theme.AppCompat.NoActionBar"> <item name="circularProgressTheme">@style/circularProgressThemeWhite</item> </style> 

Utilice la barra de progreso como a continuación

  <ProgressBar style="?attr/circularProgressTheme" android:id="@+id/commonProgress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="visible"/> 

Aquí está el código para cambiar el color de ProgressBar por programatically.

 ProgressBar progressBar = (ProgressBar) findViewById(R.id.pb_listProgressBar); int colorCodeDark = Color.parseColor("#F44336"); progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorCodeDark)); 

Esto funcionó para mí y es una solución fácil.

 progressDialog.setMessage( Html.fromHtml("<font color='white'>" + Message + "</font>")); 
  • Android ProgressBar no se actualiza onProgress
  • ContentLoadingProgressBar nunca se muestra
  • Barra de progreso con divisor
  • Barra de progreso de Android con relleno
  • ¿Cómo puedo mostrar un círculo de actividad holo-temático?
  • Cómo crear una barra de progreso circular (gráfico circular) como indicador - Android
  • Cómo personalizar una barra de progreso en Android
  • Cómo hacer progresbar circular con el estado de progreso en android?
  • Cómo acceder a la carpeta de descargas en android?
  • ¿Cómo crear una barra de progreso de carga horizontal?
  • Warcraft ProgressBar en el diseño de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.