Come cambiare il colore di avanzamento della barra di avanzamento in Android


474

Sto usando una barra di avanzamento orizzontale nella mia applicazione Android e voglio cambiarne il colore (che è giallo per impostazione predefinita). Come posso farlo usando code(non XML)?


Hai provato MyProgressBar.setProgressDrawable (Drawable d) specificando una bitmap con il colore desiderato? developer.android.com/reference/android/widget/… developer.android.com/reference/android/graphics/drawable/…
fupsduck

2
Sì, l'ho provato ma non funziona. Imposta il colore di sfondo dell'intera vista della barra di avanzamento anziché impostare il colore di sfondo della sola barra stessa. Grazie.
WhiteTigerK,

21
android:indeterminateTint="@android:color/white"funziona solo su API> = 21
Madeyedexter

Risposte:


291

Mi dispiace che non sia la risposta, ma cosa sta guidando il requisito impostandolo dal codice? E .setProgressDrawabledovrebbe funzionare se è definito correttamente

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

4
Il motivo è perché sto creando la barra di avanzamento in modo dinamico e impostando il suo colore su richiesta dell'utente. Dato che di solito utilizzo il codice per la creazione della schermata e dei componenti della mia GUI, non ho familiarità con l'XML allegato e non so cosa sia un elenco di livelli (anche se suppongo che tu stia costruendo la barra di avanzamento basata su diversi livelli ..). Nel caso in cui volessi usare l'XML che hai allegato, dove dovrei inserirlo nella cartella del progetto e c'è qualcos'altro che devo fare per creare una barra di avanzamento basata sulle impostazioni XML? Grazie.
WhiteTigerK

1
Salva questo xml come file e lo metti nella cartella di disegno (diciamo my_progress.xml) di quanto lo imposti come disegno in MyProgressBar.setProgressDrawable () Per cambiare i colori, devi cambiare questi valori in @ color / progress_start @ color / progress_end È fondamentalmente un gradiente e puoi inserire esadecimali.
Alex Volovoy,

3
Nota: il file è la copia di quello che si trova nell'SDK. Ho lasciato cadere il copyright qui. Se guardi nella cartella res / drawable vedrai esattamente quello che ho pubblicato: i colori sono impostati sul gradiente giallo, anziché sui colori personalizzati.
Alex Volovoy,

7
Non mostra alcun cambiamento di colore per me. per favore, dì il colore che ha funzionato.
Praveen,

Ciao Alex, le tue risposte sono molto carine. ma, ho provato a cambiare il colore della ruota di avanzamento personalizzata in fase di esecuzione. ma non potrei. Si prega di aiutarmi a risolvere il mio problema .. dopo il progresso reaches100%, allora questo cambiamento di tempo il colore e iniziare a codice per il download da questo progress..i .. stackoverflow.com/questions/18503718/...
Harikrishnan

485

Per una ProgressBar orizzontale, puoi usare anche una ColorFilter, come questa:

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

Barra di avanzamento rossa con filtro colorato

Nota: questo modifica l'aspetto di tutte le barre di avanzamento nella tua app. Per modificare solo una barra di avanzamento specifica, procedere come segue:

Drawable progressDrawable = progressBar.getProgressDrawable().mutate();
progressDrawable.setColorFilter(Color.RED, android.graphics.PorterDuff.Mode.SRC_IN);
progressBar.setProgressDrawable(progressDrawable);

Se progressBar è indeterminato, utilizzare getIndeterminateDrawable()invece di getProgressDrawable().

Da Lollipop (API 21) è possibile impostare una sfumatura di avanzamento:

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

Barra di avanzamento rossa utilizzando la tinta di avanzamento


7
Volevo usare questa risposta perché mi sembrava la più semplice, ma la mia barra di avanzamento è completamente rossa indipendentemente dal valore di avanzamento. Sei sicuro della modalità da utilizzare?
LG,

33
@resus Ho lo stesso problema, la barra era completamente rossa e nessun progresso era visibile. Ma l'ho risolto cambiando Mode.SRC_IN in Mode.MULTIPLY.
Derzu,

40
Non dimenticare di fare lo stesso per getIndeterminateDrawablese stai usando progressi indeterminati.
Thommy,

6
Tieni presente che "Modalità" in questo contesto si riferisce a android.graphics.PorterDuff.Mode
1owk3y

9
come non cambiare il colore di sfondo? Voglio solo cambiare il colore di avanzamento.
Canguro il

364

Questo non è programmaticamente, ma penso che potrebbe aiutare molte persone comunque.
Ho provato molto e il modo più efficiente era quello di aggiungere queste righe al mio ProgressBar nel file .xml:

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

Quindi alla fine questo codice l'ha fatto per me:

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

Questa soluzione funziona con API 21+


45
Richiede il livello minimo API 21
Apfelsaft

Esistono anche metodi setter per queste proprietà che possono essere chiamati se è necessario impostare il colore dinamico.
corse il

Devo creare un file di risorse personalizzato per api 21+ e api <= 20? Oppure questi attributi sono semplicemente ignorati in api <= 20?
prom85

1
@shriduttkothari come può essere il migliore? ... dal 21+
user25

2
La migliore risposta quando Android si sposta dal minimo 4.x
Tom

229

Per la mia barra di avanzamento indeterminata (spinner) ho appena impostato un filtro colorato sul disegno. Funziona alla grande e solo una riga.

Esempio in cui impostare il colore su rosso:

ProgressBar spinner = new android.widget.ProgressBar(
                context,
                null,
                android.R.attr.progressBarStyle);

spinner.getIndeterminateDrawable().setColorFilter(0xFFFF0000, android.graphics.PorterDuff.Mode.MULTIPLY);

inserisci qui la descrizione dell'immagine


16
Mi piace la tua risposta al meglio. Perché il mio funzioni anche se devo farlo: myProgressBarSpinner.getIndeterminateDrawable (). SetColorFilter (new LightingColorFilter (0xFF000000, foregroundColorDesired));
Art Geigel,

4
Nota anche che facendo questo modificherai i disegni di TUTTE le barre di avanzamento nella tua app. Per fare questo solo per uno in particolare, chiama mutate () su drawable, quindi imposta il filtro colore su di esso e quindi chiama setIntederminateDrawable sul tuo progressBar.
Dimsuz,

3
NB: Coloro che lo usano e si chiedono perché il loro colore non appaia esattamente come la stringa esagonale che inseriscono, ha un filtro Multiplo su di esso. Passa android.graphics.PorterDuff.Mode.MULTIPLYa PorterDuff.Mode.SRC_INe otterrai l'esatto colore esadecimale.
micnguyen,

Penso che abbia solo bisogno di questa risposta ..... android: indeterminateTint = "@ android: color / black"
Muhammad Adil,

4
ho usato come: progressBar = (ProgressBar) findViewById (R.id.progressBar); progressBar.getIndeterminateDrawable (). setColorFilter (ContextCompat.getColor (this, android.R.color.white), android.graphics.PorterDuff.Mode.MULTIPLY);
ashishdhiman2007,

189

Questa è una vecchia domanda, ma l'utilizzo del tema non è menzionato qui. Se stai usando il tuo tema predefinito AppCompat, il tuo ProgressBarcolore sarà quello colorAccentche hai definito.

La modifica colorAccentcambierà anche il ProgressBarcolore del tuo, ma le modifiche si riflettono anche in più punti. Quindi, se vuoi un colore diverso solo per uno specifico PregressBar, puoi farlo applicando il tema a quello ProgressBar:

  • Estendi il tema predefinito e sostituisci colorAccent

    <style name="AppTheme.WhiteAccent">
        <item name="colorAccent">@color/white</item> <!-- Whatever color you want-->
    </style>
  • E in ProgressBaraggiungere l' android:themeattributo:

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

Quindi sarà simile a questo:

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

Quindi stai solo cambiando un colorAccentper il tuo particolare ProgressBar.

Nota : l'utilizzo stylenon funzionerà. Devi usare android:themesolo. Puoi trovare un maggiore uso del tema qui: https://plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH


18
finalmente! grazie, sembra che non molti sviluppatori utilizzino AppCompat, molti utenti votano solo le risposte con la soluzione per API 21+, non va affatto bene, dovrebbero supportare più dispositivi / SO possibili
user25

1
Eccezionale! Ha funzionato per me, ma ho dovuto assicurarmi che ci fosse un parent = "@ style / Theme.AppCompat" da qualche parte nella gerarchia di stile che avevo un altro genitore e all'inizio non ha funzionato.
Nublodeveloper,

@Nublodeveloper Sì, l'ho detto nella prima riga se l'hai notato.
kirtan403,

1
@ kirtan403 Ah, sì, ho capito ora me lo dici, ma non l'ho capito in quel modo quando l'ho letto per la prima volta. L'ho letto troppo in fretta e cercavo il codice. Grazie comunque, la tua risposta è la migliore per me!
Nublodeveloper,

+1 Mi è piaciuta la tua soluzione. Ma come impostare il colore del tema in Java ??? Ad esempio, se voglio che sia rosso <color name = "red"> # ff5900 </color>
Maseed

54

Tutte le API

se usi tutte le API basta creare il tema con stile

style.xml

<resources>

    //...

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

</resources>

e uso in corso

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

Livello API 21 e versioni successive

se utilizzato nel livello API 21 e superiore, utilizzare questo codice:

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

1
Bello, penso che il metodo style.xml sia il migliore. (Non c'è bisogno sopra 20 api)
iamkdblue

1
La migliore soluzione se vuoi una soluzione per tutte le API Grazie :)
Naveen,

34

secondo alcuni dei suggerimenti, PUOI specificare una forma e ritraibile con un colore, quindi impostarlo. Ho questo lavoro programmaticamente. Questo è come lo faccio ..

Innanzitutto assicurati di importare la libreria disegnabile.

import android.graphics.drawable.*;

Quindi utilizzare il codice simile al seguente;

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

1
Ho provato il codice sopra, sfortunatamente risulta solo una barra di avanzamento "vuota". Mi sto perdendo qualcosa?
OceanBlue,

Devi chiamare setLevel su ClipDrawable. Prende un valore compreso tra 0 e 10000. Quindi, progress.setLevel (2500) sarebbe pieno al 25%.
HappyEngineer,

1
Ho inviato una modifica alla risposta che spiega un motivo per una barra di avanzamento "vuota" - e 2 modi per risolverlo (incl. Correzione @ HappyEngineer)
Richard Le Mesurier

@RichardLeMesurier puoi pubblicare la spiegazione + 2 modi nella sezione commenti? progress.setLevel(2500)non funziona per me e apparentemente la tua modifica non è stata accettata per qualche motivo. Grazie. +1.
ateiob,


32

Questo ha funzionato per me:

<ProgressBar
 android:indeterminateTint="#d60909"
 ... />

12
Utilizzato solo nel livello API 21 e superiore
Numair

28

se indeterminato:

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

L'ho usato, ma non si anima, è stato applicato solo il colore ... Sto usando la
barra di

24

Questo funziona per me. Funziona anche per la versione precedente. Aggiungi questo al tuo syles.xml

<style name="ProgressBarTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="colorAccent">@color/colorPrimary</item>
</style>

E usalo così in XML

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

L'ho implementato nell'app di esempio CryptoTweets . Ho scoperto che il tema principale non è necessario per far funzionare questa soluzione come previsto. parent="ThemeOverlay.AppCompat.Light"
Adam Hurwitz,

23

Oggi nel 2016 ho scoperto che alcuni dispositivi pre-Lollipop non rispettano l' colorAccentimpostazione, quindi la mia soluzione finale per tutte le API è ora la seguente:

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

Per i punti bonus, non utilizza alcun codice deprecato. Provalo!


Non dimenticare di chiamare wrapDrawable.mutate()conDrawableCompat.setTint(wrapDrawable.mutate(), ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
Tarsem Singh,

Non funziona su Android KitKat 4.4.2.
pradip tilala,

Ho appena provato (di nuovo) su un nuovo emulatore 4.4.2 e funziona senza problemi, controlla le tue .xmlimpostazioni e anche se qualcos'altro sta scavalcando il ProgressBarcolore.
Henrique de Sousa,

20

Questo è quello che ho fatto. Lavorato.

Barra di avanzamento:

<ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="4"
            android:indeterminateDrawable="@drawable/progressdrawable"
           />

progressdrawable.xml:
qui usa il gradiente per cambiare colore come preferisci. E android: toDegrees = "X" aumenta il valore di X e la barra di avanzamento ruota velocemente. Diminuisce e ruota lentamente. Personalizza in base alle tue esigenze.

<?xml version="1.0" encoding="utf-8"?>
     <rotate xmlns:android="http://schemas.android.com/apk/res/android"
            android:duration="4000"
            android:fromDegrees="0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="360" >

            <shape
                android:innerRadius="20dp"
                android:shape="ring"
                android:thickness="4dp"
                android:useLevel="false" >
                <size
                    android:height="48dp"
                    android:width="48dp" />

                <gradient
                    android:centerColor="#80ec7e2a"
                    android:centerY="0.5"
                    android:endColor="#ffec7e2a"
                    android:startColor="#00ec7e2a"
                    android:type="sweep"
                    android:useLevel="false" />
            </shape>

        </rotate>

campione: inserisci qui la descrizione dell'immagine


Questo mostra un'animazione totalmente diversa (di cattivo aspetto) rispetto a quella predefinita.
Ixx

18

Risolvi lo stesso problema mentre lavori per modificare l'aspetto della barra di avanzamento predefinita. Ecco alcune altre informazioni che speriamo possano aiutare le persone :)

  • Il nome del file xml deve contenere solo caratteri: a-z0-9_.(cioè senza maiuscole!)
  • Per fare riferimento al tuo "disegnabile" è R.drawable.filename
  • Per sovrascrivere l'aspetto predefinito, si utilizza myProgressBar.setProgressDrawable(...), tuttavia non è necessario fare semplicemente riferimento al layout personalizzato poiché R.drawable.filename, è necessario recuperarlo come Drawable:
    Resources res = getResources();
    myProgressBar.setProgressDrawable(res.getDrawable(R.drawable.filename);
  • Devi impostare lo stile prima di impostare avanzamento / avanzamento secondario / massimo (impostandolo in seguito per me ha provocato una barra di avanzamento "vuota")

15

Probabilmente c'è una cosa a cui non è stato fatto riferimento in questa risposta:

Se il tuo tema sta ereditando Theme.AppCompat, ProgressBarassumerà il colore che hai definito come "colorAccent"nel tuo tema.

Quindi, usando ..

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

..colora automaticamente il colore di ProgressBar su @color/custom_color.


1
Avevo bisogno di usare <item name = "android: colorAccent"> @ color / highlight </item>
tonisives


15

Puoi provare a cambiare i tuoi stili, temi o utilizzando android: indeterminateTint = "@ color / yourColor" dove vuoi, ma c'è solo un modo per farlo che funzionerà su qualsiasi versione di Android SKD:

Se la barra di avanzamento non è indeterminata, utilizzare:

progressBar.getProgressDrawable().setColorFilter(ContextCompat.getColor(context, R.color.yourColor), PorterDuff.Mode.SRC_IN );

Se la barra di avanzamento è indeterminata, utilizzare:

progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), R.color.yourColor), PorterDuff.Mode.SRC_IN );

È triste che Android sia un tale casino!


Grazie! Funziona per indeterminato ProgressBar, ma per determinato dipinge tutta la scala con il colore.
CoolMind,

14

Come l'ho fatto in ProgressBar orizzontale:

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

2
Ho fatto la stessa cosa, oltre al cambio colore di sfondo: layerDrawable.findDrawableByLayerId (android.R.id.background) .setColorFilter (trackColor, PorterDuff.Mode.SRC);
Kamen Dobrev,

1
Questa risposta insieme al commento di @KamenDobrev è l'unica che ha effettivamente fatto quello che volevo. Quando ho impostato solo un filtro colore sullo stato di avanzamento, anche il colore di sfondo è cambiato.
m_katsifarakis,

13

Soluzione più semplice se si desidera modificare il colore nel file xml di layout, utilizzare il codice seguente e utilizzare la proprietà indeterminateTint per il colore desiderato.

    <ProgressBar
      android:id="@+id/progressBar"
      style="?android:attr/progressBarStyle"
      android:layout_width="wrap_content"
      android:indeterminate="true"
      android:indeterminateTintMode="src_atop"
      android:indeterminateTint="#ddbd4e"
      android:layout_height="wrap_content"
      android:layout_marginBottom="20dp"
      android:layout_alignParentBottom="true"
      android:layout_centerHorizontal="true" />

12

Questa soluzione ha funzionato per me:

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

8

Ancora una piccola cosa, la soluzione del tema funziona se erediti un tema di base, quindi per un'app compatta il tuo tema dovrebbe essere:

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

E quindi impostalo nel tema della barra di avanzamento

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

7

Per cambiare il colore orizzontale ProgressBar (in kotlin):

fun tintHorizontalProgress(progress: ProgressBar, @ColorInt color: Int = ContextCompat.getColor(progress.context, R.color.colorPrimary)){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        progress.progressTintList = ColorStateList.valueOf(color)
    } else{
        val layerDrawable = progress.progressDrawable as? LayerDrawable
        val progressDrawable = layerDrawable?.findDrawableByLayerId(android.R.id.progress)
        progressDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
    }
}

Per cambiare il colore ProgressBar indeterminato:

fun tintIndeterminateProgress(progress: ProgressBar, @ColorInt color: Int = ContextCompat.getColor(progress.context, R.color.colorPrimary)){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        progress.indeterminateTintList = ColorStateList.valueOf(color)
    } else {
        (progress.indeterminateDrawable as? LayerDrawable)?.apply {
            if (numberOfLayers >= 2) {
                setId(0, android.R.id.progress)
                setId(1, android.R.id.secondaryProgress)
                val progressDrawable = findDrawableByLayerId(android.R.id.progress).mutate()
                progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
            }
        }
    }
}

E infine normalmente colorano le barre di avanzamento pre-lecca-lecca

progressi colorati su api 19


6

Stile materiale personalizzato barra di avanzamento orizzontale:

Per cambiare il colore dello sfondo e l'avanzamento della barra di avanzamento orizzontale.

<style name="MyProgressBar" parent="@style/Widget.AppCompat.ProgressBar.Horizontal">
    <item name="android:progressBackgroundTint">#69f0ae</item>
    <item name="android:progressTint">#b71c1c</item>
    <item name="android:minWidth">200dp</item>
</style>

Applicalo alla barra di avanzamento impostando l'attributo di stile, per stili di materiale personalizzati e controllo barra di avanzamento personalizzata http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples


3
ciò richiede un livello minimo di API 21
Shihab Uddin,

6

Postato per aggiungere informazioni sulla risposta di PaulieG , poiché ateiob mi ha chiesto di spiegare qualcosa ...


Posso dire che al momento della stesura di questa versione del codice sorgente Android è presente (o almeno esisteva, al momento della stesura di questo codice, un bug / problema / ottimizzazione ProgressBarche ignora un tentativo di impostare il progresso su un valore è già a.

  • vale a dire se progress = 45 e si tenta di impostarlo su 45, il codice non farà nulla e non ridisegnerà l'avanzamento .

Dopo aver chiamato ProgressBar.setProgressDrawable(), la barra di avanzamento sarà vuota (perché hai cambiato la parte disegnabile).

Ciò significa che è necessario impostare i progressi e ridisegnarli. Ma se imposti il ​​progresso su un valore preservato, non farà nulla.

Devi prima impostarlo su 0, quindi nuovamente sul valore "vecchio" e la barra verrà ridisegnata.


Quindi per riassumere:

  • preservare il "vecchio" valore di avanzamento
  • aggiorna il disegno / colore (rende vuota la barra)
  • resetta l'avanzamento a 0 (altrimenti la riga successiva non fa nulla)
  • resettare l'avanzamento al valore "vecchio" (barra delle correzioni)
  • invalidate

Di seguito è un metodo che ho che fa questo:

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

Per quanto riguarda la soluzione di HappyEngineer, penso che sia stata una soluzione simile, per impostare manualmente l'offset "avanzamento". In entrambi i casi, il codice sopra dovrebbe funzionare per te.


Grazie..questo funziona davvero..ma dato che il mio disegno era statico (dalle risorse) .. non ha funzionato. Ha funzionato solo dopo aver aggiunto "drawable.invalidateSelf ();" prima di 'setProgress (0)' e 'setProgressDrawable (drawable)'
Alécio Carvalho,


5

usa semplicemente:

PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
    mode = PorterDuff.Mode.MULTIPLY;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
    progressBar.setProgressBackgroundTintList(ColorStateList.valueOf(Color.RED));
} else {
    Drawable progressDrawable;
    progressDrawable = (progressBar.isIndeterminate() ? progressBar.getIndeterminateDrawable() : progressBar.getProgressDrawable()).mutate();
    progressDrawable.setColorFilter(context.getResources().getColor(Color.RED), mode);
    progressBar.setProgressDrawable(progressDrawable);
}

4

Per uno ProgressBar in stile orizzontale uso:

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 chiamata di esempio sarebbe:

  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

Se non hai bisogno del "progresso secondario", imposta semplicemente value2 su value1.


4

Applica questo stile personalizzato alla barra di avanzamento.

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

Utilizzare questo tipo di immagine per la barra di avanzamento. inserisci qui la descrizione dell'immagine

Per un risultato migliore è possibile utilizzare più immagini di avanzamento. E non esitare a utilizzare le immagini, poiché la stessa piattaforma Android utilizza le immagini per la barra di avanzamento. Il codice viene estratto da SDK :)


4

Come da muhammad-adil suggerito per SDK versione 21 e successive

android:indeterminateTint="@color/orange"

in XML Funziona per me, è abbastanza facile.


Se vuoi cambiare per l'intera app, cambia il valore di <color name = "RedAccent"> # FE6C27 </color>. nel tuo Values ​​/ colors.xml.
Mughil,

4

Ecco il codice per cambiare il colore di ProgressBar programmaticamente.

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

4
ProgressBar freeRamPb = findViewById(R.id.free_ram_progress_bar);

freeRamPb.getProgressDrawable().setColorFilter(
Color.BLUE, android.graphics.PorterDuff.Mode.SRC_IN);

Eccezionale. Soluzione rapida ed efficace. Grazie!
Tobias Reich,
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.