Come cambiare il colore dell'indicatore di progresso ProgressBar in Android


178

Ho impostato Orizzontale ProgressBar.

Vorrei cambiare il colore di avanzamento in giallo.

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

Il problema è che il colore di avanzamento è diverso in diversi dispositivi. Quindi, voglio che ripari il colore di avanzamento.


le risposte sopra cambiano tutto il colore di sfondo ed è ovvio che cambia l'altezza della barra di avanzamento a molto max. che non è in grado di cambiare in xml. modo migliore per cambiare solo lo stato della barra di avanzamento che quanto è completato è il 20% di colore rosso, il 50% di colore giallo 70% e sopra il colore verde. puoi farlo programmaticamente in java. condividi la tua risposta se hai un'altra soluzione.
Mubashar,

Risposte:


365

L'ho copiato da una delle mie app, quindi probabilmente ci sono alcuni attributi extra, ma dovrei darti l'idea. Questo è dal layout che ha la barra di avanzamento:

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

Quindi crea un nuovo disegno con qualcosa di simile al seguente (In questo 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>

Puoi cambiare i colori secondo necessità, questo ti darà una barra di avanzamento verde.


E rimuovo anche questo androide: indeterminate = "false"
Nishant Shah,

2
Mi aiuti per favore. Provo a creare greenprogress.xml copiando il codice, ma Android Studio 0.4.6 contrassegna <elenco-layer> come ed errore "Elenco elementi deve essere dichiarato" cosa devo fare?
UmAnusorn,

1
È possibile cambiare il colore in modo dinamico?
asincrono

il colore può essere cambiato in base all'attuale valore di avanzamento definito nella barra attuale?
Jonathan,

@Ryan Sarebbe utile spiegare cosa android:id="@android:id/progress", android:id="@android:id/background"e android:id="@android:id/secondaryProgress"rappresentare.
RustamG

103

Una soluzione più semplice:

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
qui @ color / disabled è un colore personalizzato
Nitin Saxena

2
Oppure <solido android: color = "@ android: color / black" />, o anche <solido android: color = "# ff33b5e5" />
superarts.org

2
Questo è abbastanza android: indeterminateTint = "@ color / white" per la leva API 21 e successive
Ghanshyam Nayma

53

Basta creare uno stile in values/styles.xml.

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

Quindi imposta questo stile come ProgressBartema.

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

e non importa se la barra di avanzamento è orizzontale o circolare. È tutto.


1
Wow, la soluzione più semplice, funziona per me. Mi chiedevo perché questa risposta abbia così tanti voti.
Pavel Shorokhov,

38

Se vuoi solo cambiare il colore della barra di avanzamento, puoi semplicemente usare un filtro colore nel metodo onCreate () della tua attività:

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 da qui .

Devi solo farlo per le versioni pre-lecca-lecca. Su Lollipop puoi usare l'attributo colorAccent style.


Per SeekBarè lo stesso, basta aggiungere per API 16: seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);. Questo cambierà il colore di quel pollice rotondo.
Sufian,

1
Richiamare setColorFilter()direttamente un disegno verrà applicato il colore ovunque. Dal momento che questo è ciò di cui non avevo bisogno, ho appena invitato mutate()il Drawable(cioèseekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Sufian

3
Ho visto questa soluzione altrove ma tutto ciò che fa (test su un dispositivo Gingerbread) è girare l'intera barra di avanzamento di un colore, rendendo impossibile vedere i progressi effettivi
Neil C. Obremski,

@ NeilC.Obremski sì, hai ragione. Potrebbe essere specifico della ROM o forse della versione specifica. Ho dovuto rimuoverlo del tutto. Speriamo di riportarlo presto su versioni precedenti di Android (tramite il supporto lib).
Sufian,

25

per API di livello 21 o superiore basta usare

android:progressBackgroundTint="@color/yourBackgroundColor"
android:progressTint="@color/yourColor"

6

Esistono 3 modi per risolvere questa domanda:

  1. Come regolare il colore della barra di avanzamento in modo dichiarativo
  2. Come regolare il colore della barra di avanzamento a livello di codice, ma scegliere il colore tra vari colori predeterminati dichiarati prima del tempo di compilazione
  3. Come regolare il colore della barra di avanzamento a livello di codice e anche creare il colore a livello di codice.

In particolare c'è molta confusione tra # 2 e # 3, come si vede nei commenti alla risposta di amfcosta. Quella risposta produrrà risultati di colore imprevedibili ogni volta che desideri impostare la barra di avanzamento su qualsiasi cosa tranne i colori primari, poiché modifica solo il colore di sfondo e l'area della "clip" della barra di avanzamento effettiva sarà comunque una sovrapposizione gialla con opacità ridotta. Ad esempio, l'utilizzo di questo metodo per impostare lo sfondo su viola scuro provocherà un colore "clip" della barra di avanzamento di un pazzo colore rosato risultante dalla miscelazione di viola scuro e giallo tramite alfa ridotta.

Quindi, comunque, il numero 1 riceve una risposta perfetta da Ryan e Štarke risponde alla maggior parte del numero 3, ma per coloro che cercano una soluzione completa per i numeri 2 e 3:


Come regolare il colore della barra di avanzamento a livello di codice, ma scegliere il colore da un colore predeterminato dichiarato in XML

res / drawable / my_progressbar.xml :

Crea questo file ma modifica i colori in my_progress e my_secondsProgress:

(NOTA: questa è solo una copia del file XML effettivo che definisce ProgressBar dell'SDK Android predefinito, ma ho cambiato ID e colori. L'originale si chiama 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>

Nel tuo 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)

Come regolare il colore della barra di avanzamento a livello di codice e anche creare il colore a livello di codice

MODIFICARE: ho trovato il tempo per risolverlo correttamente. La mia precedente risposta ha lasciato questo un po 'ambiguo.

Un ProgressBar è composto da 3 Drawable in un LayerDrawable.

  1. Il livello 1 è lo sfondo
  2. Il livello 2 è il colore di avanzamento secondario
  3. Il livello 3 è il colore principale della barra di avanzamento

Nell'esempio seguente cambierò il colore della barra di avanzamento principale in ciano.

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

Quell'esempio lo ha impostato su un colore solido. È possibile impostarlo su un colore sfumato sostituendolo

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

Saluti.

-Lancia


cos'è viewUtils in viewUtils.convertDpToPixel (5);
Nikos Hidalgo,

1
Ciao @NikosHidalgo - Puoi vedere un metodo quasi identico qui: stackoverflow.com/questions/12849366/… . L'unica differenza è che costruisco il mio ViewUtilscon riferimento a Context, quindi non ho bisogno di passare un Contextquando chiamoconvertDpToPixel()
lance.dolan

Grazie per la pronta risposta, in particolare per una risposta che è stata pubblicata molto tempo fa!
Nikos Hidalgo,

Ahah, dovevo davvero allungare il cervello per ricordare: p
lance.dolan,

4

Se ti trovi al livello API 21 o superiore, puoi utilizzare questi attributi XML:

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

3

La soluzione più semplice che ho scoperto è qualcosa del genere:

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

Metti il styles.xmlfile sopra nella res > valuescartella.

NOTA: se si utilizza qualsiasi altro colore accento, le soluzioni precedenti dovrebbero essere adatte.

API 21 o SUPERIORE


Questa è la soluzione migliore. 100% correlato alla domanda posta. molto semplice
Pir Fahim Shah,

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

1
Prova ad aggiungere una piccola spiegazione alla tua risposta. Le risposte solo al codice sono scoraggiate.
Alexei,

Mi piacerebbe avere una spiegazione dietro l'indice 2 in getDrawable, ma almeno questa è stata l'unica soluzione che ha funzionato per me, quindi grazie!
Nikos Hidalgo,

2

Per chiunque cerchi come farlo a livello di codice:

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

L'impostazione degli ID su drawable è fondamentale e si occupa di preservare i limiti e l'effettivo stato di avanzamento della barra


1

Ragazzi, mi state davvero facendo venire il mal di testa. Quello che puoi fare è rendere il tuo elenco di livelli da disegnare prima tramite xml (ovvero uno sfondo come primo livello, un disegno che rappresenta il progresso secondario come secondo livello e un altro disegno che rappresenta il progresso primario come ultimo livello), quindi cambia il colore sul codice procedendo come segue:

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

Questo metodo ti darà la massima flessibilità di avere la misura del tuo disegno originale dichiarata sull'xml, SENZA MODIFICHE SUCCESSIVE ALLA STRUTTURA, specialmente se hai bisogno di avere la cartella dello schermo del file xml specifica, quindi modificare SOLO IL COLORE tramite il codice. Nessuna nuova istanza di una nuova ShapeDrawable da zero.


1

Il colore ProgressBar può essere modificato come segue:

/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

Crea una risorsa disegnabile di quale sfondo hai bisogno, nel mio caso l'ho chiamato 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>

Quindi utilizzare questo sfondo personalizzato come

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

Funziona bene per me


0

In 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

Con la Libreria dei componenti materiali è possibile utilizzare ProgressIndicatorl' app:indicatorColorattributo with per modificare il colore:

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

inserisci qui la descrizione dell'immagine

Nota : richiede almeno la versione 1.3.0-alpha01.

Con il ProgressBarpuoi sovrascrivere il colore usando:

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

con:

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

inserisci qui la descrizione dell'immagine


0

Se desideri impostare il colore di avanzamento primario e secondario sulla barra di avanzamento orizzontale a livello di codice in Android, utilizza lo snippet di seguito

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));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.