So ändern Sie die Farbe der Fortschrittsanzeige von ProgressBar in Android

178

Ich habe Horizontal eingestellt ProgressBar.

Ich möchte die Fortschrittsfarbe in Gelb ändern.

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

Das Problem ist, dass die Fortschrittsfarbe bei verschiedenen Geräten unterschiedlich ist. Ich möchte also, dass die Fortschrittsfarbe korrigiert wird.

Nishant Shah
quelle
Die obigen Antworten ändern die gesamte Hintergrundfarbe und es ist zweideutig, dass die Höhe des Fortschrittsbalkens auf sehr maximal geändert wird, was sich in XML nicht ändern kann. Besser ist es, nur den Status des Fortschrittsbalkens zu ändern, wenn 20% rote Farbe, 50% gelbe Farbe 70% und mehr grüne Farbe sind. Sie können dies programmgesteuert in Java tun. Teilen Sie Ihre Antwort mit, wenn Sie eine andere Lösung haben.
Mubashar

Antworten:

365

Ich habe dies von einer meiner Apps kopiert, daher gibt es wahrscheinlich ein paar zusätzliche Attribute, aber ich sollte Ihnen die Idee geben. Dies ist aus dem Layout mit dem Fortschrittsbalken:

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

Erstellen Sie dann eine neue Zeichnung mit einer ähnlichen Darstellung (in diesem Fall 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>

Sie können die Farben nach Bedarf ändern. Dadurch erhalten Sie einen grünen Fortschrittsbalken.

Ryan
quelle
Und auch ich entferne dieses Android: unbestimmt = "falsch"
Nishant Shah
2
Bitte hilf mir. Ich versuche, greenprogress.xml durch Kopieren Ihres Codes zu erstellen, aber Android Studio 0.4.6 markiert <Layer-Liste> als und Fehler "Elementliste muss deklariert werden". Was soll ich tun?
UmAnusorn
1
Ist es möglich, die Farbe dynamisch zu ändern?
Async
Kann die Farbe abhängig vom aktuellen Fortschrittswert geändert werden, der in der tatsächlichen Leiste definiert ist?
Jonathan
@ Ryan Es wäre hilfreich , was zu erklären android:id="@android:id/progress", android:id="@android:id/background"und android:id="@android:id/secondaryProgress"steht.
RustamG
103

Eine einfachere Lösung:

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
quelle
1
hier @ Farbe / deaktiviert ist eine benutzerdefinierte Farbe
Nitin Saxena
2
Oder <solid android: color = "@ android: color / black" /> oder sogar <solid android: color = "# ff33b5e5" />
superarts.org
2
Dies ist genug android: indeterminateTint = "@ color / white" für API-Hebel 21 und höher
Ghanshyam Nayma
53

Erstellen Sie einfach einen Stil in values/styles.xml.

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

Dann legen Sie diesen Stil als Ihr ProgressBarThema fest.

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

und egal, Ihr Fortschrittsbalken ist horizontal oder kreisförmig. Das ist alles.

Ali Zeynali
quelle
1
Wow, die einfachste Lösung, funktioniert bei mir. Ich habe mich gefragt, warum diese Antwort so viele Stimmen hat.
Pavel Shorokhov
38

Wenn Sie nur die Farbe des Fortschrittsbalkens ändern möchten, können Sie einfach einen Farbfilter in der onCreate () -Methode Ihrer Aktivität verwenden:

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

Idee von hier .

Sie müssen dies nur für Pre-Lollipop-Versionen tun. Auf Lollipop können Sie das styleAccent-Stilattribut verwenden.

Amfcosta
quelle
Fügen SeekBarSie für API 16 einfach Folgendes hinzu : seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);. Dadurch wird die Farbe dieses runden Daumens geändert.
Sufian
1
Der Aufruf setColorFilter()auf einem ziehbar wird direkt die Farbe überall anwenden. Da dies das ist, was ich nicht brauchte, rief ich einfach mutate()am Drawable(dh wieseekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Sufian
3
Ich habe diese Lösung an anderer Stelle gesehen, aber alles, was sie tut (Testen auf einem Lebkuchengerät), ist, den gesamten Fortschrittsbalken um eine Farbe zu drehen, so dass es unmöglich ist, den tatsächlichen Fortschritt zu sehen
Neil C. Obremski
@ NeilC.Obremski ja du hast recht Es kann ROM-spezifisch oder möglicherweise versionsspezifisch sein. Ich musste es komplett entfernen. Hoffentlich wird dies bald wieder auf ältere Android-Versionen portiert (via support lib).
Sufian
25

Für API Level 21 oder höher verwenden Sie einfach

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

Es gibt drei Möglichkeiten, um diese Frage zu lösen:

  1. So passen Sie die Farbe des Fortschrittsbalkens deklarativ an
  2. So passen Sie die Farbe des Fortschrittsbalkens programmgesteuert an, wählen Sie jedoch die Farbe aus verschiedenen vor der Kompilierungszeit deklarierten Farben aus
  3. So passen Sie die Farbe des Fortschrittsbalkens programmgesteuert an und erstellen die Farbe programmgesteuert.

Insbesondere bei # 2 und # 3 herrscht große Verwirrung, wie aus den Kommentaren zu amfcostas Antwort hervorgeht. Diese Antwort führt zu unvorhersehbaren Farbergebnissen, wenn Sie den Fortschrittsbalken auf etwas anderes als Primärfarben setzen möchten, da nur die Hintergrundfarbe geändert wird und der tatsächliche "Clip" -Bereich des Fortschrittsbalkens weiterhin eine gelbe Überlagerung mit reduzierter Deckkraft ist. Wenn Sie beispielsweise diese Methode verwenden, um den Hintergrund auf dunkelviolett einzustellen, wird eine Fortschrittsbalken-Clip-Farbe mit einer verrückten rosa Farbe angezeigt, die sich aus der Vermischung von dunkelviolett und gelb über reduziertes Alpha ergibt.

Wie auch immer, # 1 wird perfekt von Ryan beantwortet und Štarke beantwortet die meisten von # 3, aber für diejenigen, die nach einer vollständigen Lösung für # 2 und # 3 suchen:


So passen Sie die Farbe des Fortschrittsbalkens programmgesteuert an, wählen jedoch die Farbe aus einer in XML deklarierten vorgegebenen Farbe aus

res / drawable / my_progressbar.xml :

Erstellen Sie diese Datei, aber ändern Sie die Farben in my_progress und my_secondsProgress:

(HINWEIS: Dies ist nur eine Kopie der eigentlichen XML-Datei, die die standardmäßige Android SDK ProgressBar definiert, aber ich habe die IDs und Farben geändert. Das Original heißt 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>

In Ihrem 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)

So passen Sie die Farbe des Fortschrittsbalkens programmgesteuert an und erstellen die Farbe programmgesteuert

EDIT: Ich habe die Zeit gefunden, dies richtig zu lösen. Meine frühere Antwort ließ dies etwas mehrdeutig.

Eine ProgressBar besteht aus 3 Drawables in einem LayerDrawable.

  1. Schicht 1 ist der Hintergrund
  2. Schicht 2 ist die sekundäre Fortschrittsfarbe
  3. Ebene 3 ist die Hauptfarbe des Fortschrittsbalkens

Im folgenden Beispiel werde ich die Farbe des Hauptfortschrittsbalkens in Cyan ändern.

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

In diesem Beispiel wurde eine Volltonfarbe festgelegt. Sie können durch Ersetzen eine Verlaufsfarbe festlegen

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

mit

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

Prost.

-Lanze

lance.dolan
quelle
Was ist viewUtils in viewUtils.convertDpToPixel (5)?
Nikos Hidalgo
1
Hallo @NikosHidalgo - Sie können hier eine nahezu identische Methode sehen: stackoverflow.com/questions/12849366/… . Der einzige Unterschied ist, dass ich meine ViewUtilsmit einem Verweis auf konstruiere Context, so dass ich Contextbeim Aufruf vonconvertDpToPixel()
lance.dolan
Vielen Dank für Ihre schnelle Antwort, insbesondere auf eine Antwort, die vor so langer Zeit veröffentlicht wurde!
Nikos Hidalgo
Haha, ich musste wirklich mein Gehirn strecken, um mich zu erinnern: p
lance.dolan
4

Wenn Sie sich in API-Level 21 oder höher befinden, können Sie die folgenden XML-Attribute verwenden:

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

Die einfachste Lösung, die ich herausgefunden habe, ist ungefähr so:

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

Legen Sie die oben genannten in styles.xmlDatei unter res > valuesOrdner.

HINWEIS: Wenn Sie eine andere Akzentfarbe verwenden, sollten die vorherigen Lösungen gut geeignet sein.

API 21 oder höher

Sazid
quelle
Dies ist die beste Lösung. 100% bezogen auf die gestellte Frage. sehr einfach
Pir Fahim Shah
3
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.getDrawable(2).setColorFilter(color,PorterDuff.Mode.SRC_IN);
user3135773
quelle
1
Versuchen Sie, Ihrer Antwort eine kleine Erklärung hinzuzufügen. Nur-Code-Antworten werden nicht empfohlen.
Alexei
Ich würde gerne eine Erklärung hinter dem Index 2 in getDrawable erhalten, aber zumindest war dies die einzige Lösung, die für mich funktioniert hat, also danke!
Nikos Hidalgo
2

Für alle, die programmatisch vorgehen möchten:

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

Das Festlegen von IDs für Drawables ist von entscheidender Bedeutung und sorgt dafür, dass die Grenzen und der aktuelle Status des Fortschrittsbalken erhalten bleiben

Štarke
quelle
1

Ihr macht mir wirklich Kopfschmerzen. Was Sie tun können, ist , Ihre Ebenenliste zuerst über XML zeichnbar zu machen (dh einen Hintergrund als erste Ebene, eine Zeichnung, die den sekundären Fortschritt als zweite Ebene darstellt, und eine andere Zeichnung, die den primären Fortschritt als letzte Ebene darstellt) und dann zu ändern Geben Sie die Farbe auf dem Code wie folgt ein:

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

Diese Methode bietet Ihnen die beste Flexibilität, wenn Sie die Messung Ihres ursprünglichen Zeichnungsobjekts auf der XML deklarieren möchten, ohne Änderungen an der Struktur im Nachhinein vorzunehmen, insbesondere wenn Sie den spezifischen Ordner für den XML-Dateibildschirm benötigen und dann NUR DIE FARBE über die XML-Datei ändern müssen Code. Kein erneutes Instanziieren eines neuen ShapeDrawable von Grund auf neu.

Pier Betos
quelle
1

Die ProgressBar-Farbe kann wie folgt geändert werden:

/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
quelle
1

Erstellen Sie eine zeichnbare Ressource, deren Hintergrund Sie benötigen. In meinem Fall habe ich sie bg_custom_progressbar.xml genannt

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

Dann verwenden Sie diesen benutzerdefinierten Hintergrund wie

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

Es funktioniert gut für mich

Md Juyel Rana
quelle
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
    }
Soumen Das
quelle
0

Mit der Materialkomponentenbibliothek können Sie das ProgressIndicatormit dem app:indicatorColorAttribut with verwenden , um die Farbe zu ändern:

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

Geben Sie hier die Bildbeschreibung ein

Hinweis : Es ist mindestens die Version erforderlich 1.3.0-alpha01.

Mit dem können ProgressBarSie die Farbe überschreiben mit:

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

mit:

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

Geben Sie hier die Bildbeschreibung ein

Gabriele Mariotti
quelle
0

Wenn Sie die primäre und sekundäre Fortschrittsfarbe programmgesteuert in Android auf den horizontalen Fortschrittsbalken setzen möchten, verwenden Sie das folgende Snippet

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
quelle