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.


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.


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>

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.


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.


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"

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


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"

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


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

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


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.


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

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


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

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


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));
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.