So ändern Sie die Fortschrittsfarbe des Fortschrittsbalkens in Android


473

Ich verwende in meiner Android-Anwendung einen horizontalen Fortschrittsbalken und möchte dessen Fortschrittsfarbe ändern (standardmäßig gelb). Wie kann ich das mit code(nicht XML) machen?


Haben Sie MyProgressBar.setProgressDrawable (Drawable d) ausprobiert und eine Bitmap mit der gewünschten Farbe angegeben? developer.android.com/reference/android/widget/… developer.android.com/reference/android/graphics/drawable/…
fupsduck

2
Ja, ich habe es versucht, aber es funktioniert nicht. Hiermit wird die Hintergrundfarbe der gesamten Fortschrittsbalkenansicht festgelegt, anstatt nur die Hintergrundfarbe der Leiste selbst festzulegen. Vielen Dank.
WhiteTigerK

21
android:indeterminateTint="@android:color/white"funktioniert nur auf API> = 21
Madeyedexter

Antworten:


290

Es tut mir leid, dass dies nicht die Antwort ist, aber was treibt die Anforderung an, sie aus dem Code festzulegen? Und .setProgressDrawablesollte funktionieren, wenn es richtig definiert ist

<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
Der Grund dafür ist, dass ich den Fortschrittsbalken dynamisch erstelle und seine Farbe auf Benutzeranforderung festlege. Da ich normalerweise Code zum Erstellen meines GUI-Bildschirms und meiner Komponenten verwende, bin ich mit dem angehängten XML nicht vertraut und weiß nicht, was eine Ebenenliste ist (obwohl ich vermute, dass Sie den Fortschrittsbalken auf der Grundlage mehrerer Ebenen erstellen ..). Falls ich das angehängte XML verwenden möchte - wo soll ich es im Projektordner ablegen und muss ich noch etwas tun, um einen Fortschrittsbalken basierend auf den XML-Einstellungen zu erstellen? Vielen Dank.
WhiteTigerK

1
Sie speichern diese XML-Datei als Datei und legen sie im Zeichenordner (z. B. my_progress.xml) ab, bevor Sie sie in MyProgressBar.setProgressDrawable () als Zeichenvorlage festlegen. Um die Farben zu ändern, müssen Sie diese Werte in @ color / ändern progress_start @ color / progress_end Es ist im Grunde ein Farbverlauf und Sie können dort Hex einfügen.
Alex Volovoy

3
Hinweis - Die Datei ist die Kopie der Datei im SDK. Ich habe das Urheberrecht hier fallen gelassen. Wenn Sie in den Ordner res / drawable schauen, sehen Sie genau, was ich gepostet habe - Farben werden auf den gelben Farbverlauf anstatt auf benutzerdefinierte Farben gesetzt.
Alex Volovoy

7
Es zeigt mir keine Farbveränderung. Bitte geben Sie die Farbe an, die geklappt hat.
Praveen

Hallo Alex, deine Antworten sind sehr nett. Aber ich werde versucht, die Farbe des benutzerdefinierten Fortschrittsrads zur Laufzeit zu ändern. aber ich konnte nicht. Bitte helfen Sie mir, mein Problem zu lösen. Nachdem der Fortschritt 100% erreicht hat, ändern Sie diesmal die Farbe und starten Sie den Fortschritt. Ich
lade den

485

Für eine horizontale ProgressBar können Sie auch Folgendes verwenden ColorFilter:

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

Rote ProgressBar mit Farbfilter

Hinweis: Dadurch wird das Erscheinungsbild aller Fortschrittsbalken in Ihrer App geändert. Gehen Sie folgendermaßen vor, um nur einen bestimmten Fortschrittsbalken zu ändern:

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

Wenn progressBar unbestimmt ist, verwenden Sie getIndeterminateDrawable()anstelle von getProgressDrawable().

Seit Lollipop (API 21) können Sie eine Fortschrittsfarbe festlegen:

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

Rote Fortschrittsanzeige mit Fortschrittsfarbe


7
Ich wollte diese Antwort verwenden, da sie mir am einfachsten erschien, aber mein Fortschrittsbalken ist unabhängig vom Fortschrittswert vollständig rot. Sind Sie sicher, welchen Modus Sie verwenden sollen?
LG

33
@resus Ich habe das gleiche Problem, der Balken war vollständig rot und es war kein Fortschritt sichtbar. Aber ich habe es gelöst, indem ich Mode.SRC_IN in Mode.MULTIPLY geändert habe.
Derzu

40
Vergessen Sie nicht, dasselbe zu tun, getIndeterminateDrawablewenn Sie unbestimmten Fortschritt verwenden.
Thommy

6
Beachten
Sie

9
Wie ändere ich die Hintergrundfarbe nicht? Ich möchte nur die Fortschrittsfarbe ändern.
Kangear

364

Dies ist nicht programmatisch, aber ich denke, es könnte trotzdem vielen Menschen helfen.
Ich habe viel versucht und der effizienteste Weg war, diese Zeilen zu meiner ProgressBar in der XML-Datei hinzuzufügen:

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

Am Ende hat dieser Code es für mich getan:

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

Diese Lösung funktioniert für API 21+


45
Benötigt Mindest-API-Level 21
Apfelsaft

Es gibt auch Setter-Methoden für diese Eigenschaften, die aufgerufen werden können, wenn eine dynamische Farbe festgelegt werden muss.
Rennen

Muss ich eine benutzerdefinierte Ressourcendatei für API 21+ und API <= 20 erstellen? Oder werden diese Attribute in api <= 20 einfach ignoriert?
prom85

1
@shriduttkothari wie kann es das beste sein? ... es von 21+
user25

2
Die beste Antwort, wenn Android von 4.x Minimum abweicht
Tom

229

Für meinen unbestimmten Fortschrittsbalken (Spinner) habe ich einfach einen Farbfilter für das Zeichenelement festgelegt. Funktioniert super und nur eine Zeile.

Beispiel, bei dem die Farbe auf Rot gesetzt wird:

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

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

Geben Sie hier die Bildbeschreibung ein


16
Ihre Antwort gefällt mir am besten. Damit meine funktioniert, musste ich Folgendes tun: myProgressBarSpinner.getIndeterminateDrawable (). SetColorFilter (neuer LightingColorFilter (0xFF000000, foregroundColorDesired));
Art Geigel

4
Beachten Sie außerdem, dass dadurch die Zeichen aller Fortschrittsbalken in Ihrer App geändert werden. Um dies nur für einen bestimmten Vorgang zu tun, rufen Sie mutate () für drawable auf, setzen Sie dann den Farbfilter darauf und rufen Sie dann setIntederminateDrawable für Ihre progressBar auf.
Dimsuz

3
NB: Diejenigen, die dies verwenden und sich fragen, warum ihre Farbe nicht genau wie die von ihnen eingegebene Hex-Zeichenfolge aussieht, haben einen Mehrfarbenfilter. Wechseln Sie android.graphics.PorterDuff.Mode.MULTIPLYzu PorterDuff.Mode.SRC_INund Sie erhalten die genaue Hex-Farbe.
Micnguyen

Ich denke, er braucht nur diese Antwort ..... android: indeterminateTint = "@ android: color / black"
Muhammad Adil

4
Ich habe verwendet als: progressBar = (ProgressBar) findViewById (R.id.progressBar); progressBar.getIndeterminateDrawable (). setColorFilter (ContextCompat.getColor (this, android.R.color.white), android.graphics.PorterDuff.Mode.MULTIPLY);
ashishdhiman2007

188

Dies ist eine alte Frage, aber die Verwendung eines Themas wird hier nicht erwähnt. Wenn Ihr Standardthema verwendet wird, AppCompatist Ihre ProgressBarFarbecolorAccent Sie definiert haben.

Durch Ändern colorAccentwird auch die ProgressBarFarbe Ihres Körpers geändert , aber Änderungen werden auch an mehreren Stellen angezeigt. Also, wenn Sie eine andere Farbe nur für eine bestimmte wollenPregressBar , können Sie dies tun, indem Sie ein Thema darauf anwenden ProgressBar:

  • Erweitern Sie Ihr Standarddesign und überschreiben Sie es colorAccent

    <style name="AppTheme.WhiteAccent">
        <item name="colorAccent">@color/white</item> <!-- Whatever color you want-->
    </style>
  • Und dazu ProgressBarnoch dasandroid:theme Attribut :

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

Es wird also ungefähr so ​​aussehen:

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

Sie ändern also nur a colorAccent für Ihre spezielle ProgressBar.

Hinweis : Die Verwendung stylefunktioniert nicht. Sie müssen android:themenur verwenden. Weitere Informationen zum Thema finden Sie hier: https://plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH


18
endlich! danke, es scheint, als ob nicht viele Entwickler AppCompat verwenden, viele Benutzer stimmen nur mit Antworten für die Lösung für API 21+ ab, überhaupt nicht gut, sie sollten mehr Geräte / Betriebssysteme als möglich unterstützen
user25

1
Genial! Arbeitete für mich, aber ich musste sicherstellen, dass irgendwo in der Stilhierarchie ein Elternteil = "@ style / Theme.AppCompat" vorhanden war. Ich hatte ein anderes Elternteil und es funktionierte zunächst nicht.
Nublodeveloper

@Nublodeveloper Ja, das habe ich in der ersten Zeile erwähnt, wenn Sie es bemerkt haben.
Kirtan403

1
@ kirtan403 Ah, ja, ich verstehe, jetzt erwähnen Sie es, aber ich habe es nicht so verstanden, als ich es zum ersten Mal las. Ich habe es zu schnell gelesen und nach Code gesucht. Trotzdem danke, deine Antwort ist die beste für mich!
Nublodeveloper

+1 Hat deine Lösung gefallen. Aber wie kann man die Farbe des Themas in Java einstellen ??? Zum Beispiel, wenn ich möchte, dass es rot ist <color name = "red"> # ff5900 </ color>
Maseed

54

Alle API

Wenn Sie alle APIs verwenden, erstellen Sie das Thema einfach mit Stil

style.xml

<resources>

    //...

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

</resources>

und in Bearbeitung verwenden

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

API Level 21 und höher

Wenn Sie in API Level 21 und höher verwendet werden, verwenden Sie einfach diesen Code:

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

1
Schön, ich denke, style.xml Methode ist am besten. (Keine Notwendigkeit über 20 api)
iamkdblue

1
Beste Lösung, wenn Sie eine Lösung für alle APIs möchten Danke :)
Naveen

34

Gemäß einigen Vorschlägen können Sie eine Form und einen Clip mit einer Farbe angeben und dann festlegen. Ich habe dies programmatisch arbeiten. So mache ich das ..

Stellen Sie zunächst sicher, dass Sie die Zeichenbibliothek importieren.

import android.graphics.drawable.*;

Verwenden Sie dann den folgenden Code.

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
Ich habe den obigen Code ausprobiert, leider führt dies nur zu einem "leeren" Fortschrittsbalken. Vermisse ich etwas
OceanBlue

Sie müssen setLevel in ClipDrawable aufrufen. Es nimmt einen Wert von 0 bis 10000 an. Progress.setLevel (2500) wäre also zu 25% voll.
HappyEngineer

1
Ich habe eine Antwort auf die Antwort eingereicht, die einen Grund für einen "leeren" Fortschrittsbalken erklärt - und zwei Möglichkeiten, dies zu beheben (einschließlich @ HappyEngineers Korrektur)
Richard Le Mesurier

@RichardLeMesurier kannst du die Erklärung + 2 Möglichkeiten im Kommentarbereich posten? progress.setLevel(2500)funktioniert bei mir nicht und anscheinend wurde deine Bearbeitung aus irgendeinem Grund nicht akzeptiert. Vielen Dank. +1.
Ateiob


32

Das hat bei mir funktioniert:

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

12
Wird nur in API Level 21 und höher verwendet
Numair

28

wenn unbestimmt:

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

Ich habe dies verwendet, aber es wird nicht animiert, nur Farbe wurde angewendet ... Ich verwende einen kreisförmigen Fortschrittsbalken
Manikandan

24

Das funktioniert bei mir. Es funktioniert auch für niedrigere Versionen. Fügen Sie dies Ihrer syles.xml hinzu

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

Und benutze es so in xml

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

Ich habe dies in der CryptoTweets- Beispiel-App implementiert . Ich habe festgestellt, dass das übergeordnete Thema nicht erforderlich ist, damit diese Lösung wie erwartet funktioniert. parent="ThemeOverlay.AppCompat.Light"
Adam Hurwitz

23

Heutzutage habe ich im Jahr 2016 festgestellt, dass einige Pre-Lollipop-Geräte diese colorAccentEinstellung nicht einhalten. Meine endgültige Lösung für alle APIs lautet nun wie folgt:

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

Für Bonuspunkte wird kein veralteter Code verwendet. Versuch es!


Vergessen Sie nicht, wrapDrawable.mutate()mitDrawableCompat.setTint(wrapDrawable.mutate(), ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
Tarsem Singh

Funktioniert nicht mit Android KitKat 4.4.2.
Pradip Tilala

Probieren Sie es einfach (erneut) auf einem neuen 4.4.2-Emulator aus und es funktioniert ohne Probleme. Überprüfen Sie Ihre .xmlEinstellungen und auch, ob etwas anderes die ProgressBarFarbe überschreibt .
Henrique de Sousa

20

Das habe ich getan. Hat funktioniert.

Fortschrittsanzeige:

<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:
Verwenden Sie hier den Farbverlauf, um die Farbe nach Ihren Wünschen zu ändern. Und android: toDegrees = "X" erhöht den Wert von X und der Fortschrittsbalken dreht sich schnell. Verringern Sie und es dreht sich langsam. Passen Sie an Ihre Bedürfnisse an.

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

Stichprobe: Geben Sie hier die Bildbeschreibung ein


Dies zeigt eine völlig andere (schlecht aussehende) Animation als die Standardanimation.
Ixx

18

Treffen Sie das gleiche Problem, während Sie daran arbeiten, das Erscheinungsbild des Standard-Fortschrittsbalkens zu ändern. Hier sind einige weitere Informationen, die hoffentlich den Menschen helfen werden :)

  • Der Name der XML-Datei darf nur Zeichen enthalten: a-z0-9_.(dh keine Großbuchstaben!)
  • Um auf Ihr "zeichnbares" zu verweisen, ist es R.drawable.filename
  • Um das Standard-Erscheinungsbild zu überschreiben, das Sie verwenden myProgressBar.setProgressDrawable(...), müssen Sie sich jedoch nicht nur auf Ihr benutzerdefiniertes Layout beziehen, sondern R.drawable.filenamemüssen es wie folgt abrufen Drawable:
    Resources res = getResources();
    myProgressBar.setProgressDrawable(res.getDrawable(R.drawable.filename);
  • Sie müssen den Stil festlegen, bevor Sie den Fortschritt / den sekundären Fortschritt / das Maximum einstellen (das anschließende Festlegen für mich führte zu einem 'leeren' Fortschrittsbalken).

15

Es gibt wahrscheinlich eine Sache, auf die in dieser Antwort nicht Bezug genommen wurde:

Wenn Ihr Thema von erbt Theme.AppCompat, ProgressBarwird die Farbe angenommen, die Sie "colorAccent"in Ihrem Thema definiert haben.

Also mit ..

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

..wird die Farbe der ProgressBar automatisch auf die @color/custom_color.


1
Ich musste <item name = "android: colorAccent"> @ color / Highlight </ item>
Tonisives


15

Sie können versuchen, Ihre Stile, Designs oder Android zu ändern: indeterminateTint = "@ color / yourColor", wo immer Sie möchten, aber es gibt nur eine Möglichkeit, die auf jeder Android SKD-Version funktioniert:

Wenn Ihr Fortschrittsbalken nicht unbestimmt ist, verwenden Sie bitte:

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

Wenn Ihr Fortschrittsbalken unbestimmt ist, verwenden Sie bitte:

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

Es ist traurig, dass Android so ein Durcheinander ist!


Vielen Dank! Es funktioniert für unbestimmt ProgressBar, aber für bestimmt malt es ganze Skala mit Farbe.
CoolMind

14

Wie ich es in der horizontalen ProgressBar gemacht habe:

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

2
Ich habe das Gleiche getan und die Hintergrundfarbe geändert: layerDrawable.findDrawableByLayerId (android.R.id.background) .setColorFilter (trackColor, PorterDuff.Mode.SRC);
Kamen Dobrev

1
Diese Antwort zusammen mit @KamenDobrevs Kommentar ist die einzige, die tatsächlich getan hat, was ich wollte. Wenn ich nur einen Farbfilter auf den Fortschrittszeichner eingestellt habe, hat sich auch die Hintergrundfarbe geändert.
m_katsifarakis

13

Einfachste Lösung Wenn Sie die Farbe in der XML-Layoutdatei ändern möchten, verwenden Sie den folgenden Code und verwenden Sie die Eigenschaft indeterminateTint für die gewünschte Farbe.

    <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

Diese Lösung hat bei mir funktioniert:

<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

Eine weitere Kleinigkeit: Die Themenlösung funktioniert, wenn Sie ein Basisthema erben. Für App Compact sollte Ihr Thema also wie folgt lauten:

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

Und setzen Sie dies dann im Thema Fortschrittsbalken

<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

So ändern Sie die horizontale ProgressBar-Farbe (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)
    }
}

So ändern Sie die unbestimmte ProgressBar-Farbe:

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

Und schließlich färbt es normalerweise Pre-Lollipop ProgressBars

getönte Fortschritte auf API 19


6

Benutzerdefinierter Materialstil des horizontalen Fortschrittsbalkens:

Zum Ändern der Hintergrundfarbe und des Fortschritts des horizontalen Fortschrittsbalkens.

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

Wenden Sie es auf den Fortschrittsbalken an, indem Sie das Stilattribut festlegen. Informationen zu benutzerdefinierten Materialstilen und benutzerdefinierten Fortschrittsbalken finden Sie unter http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples


3
Dies erfordert mindestens API-Level 21
Shihab Uddin

6

Gepostet , um Informationen über die Antwort von PaulieG hinzuzufügen , da ateiob mich gebeten hat, etwas zu erklären ...


Ich kann sagen, dass es (oder zumindest zum Zeitpunkt des Schreibens, als ich mir diese aktuelle Version des Android-Quellcodes ansah) einen Fehler / ein Problem / eine Optimierung im ProgressBarCode gibt, der den Versuch ignoriert, den Fortschritt auf einen Wert zu setzen ist schon bei.

  • Wenn also progress = 45 ist und Sie versuchen, ihn auf 45 zu setzen, führt der Code nichts aus und zeichnet den Fortschritt nicht neu .

Nach dem Aufruf ProgressBar.setProgressDrawable()ist Ihr Fortschrittsbalken leer (weil Sie den zeichnbaren Teil geändert haben).

Dies bedeutet, dass Sie den Fortschritt festlegen und neu zeichnen müssen. Wenn Sie den Fortschritt jedoch nur auf einen beibehaltenen Wert setzen, wird nichts unternommen.

Sie müssen es zuerst auf 0 und dann wieder auf den "alten" Wert setzen, und der Balken wird neu gezeichnet.


Um es zusammenzufassen:

  • Behalten Sie den "alten" Fortschrittswert bei
  • Aktualisiere das Zeichen / die Farbe (macht den Balken leer)
  • Setzen Sie den Fortschritt auf 0 zurück (andernfalls führt die nächste Zeile nichts aus)
  • Setzen Sie den Fortschritt auf den "alten" Wert zurück (Korrekturleiste)
  • ungültig machen

Unten ist eine Methode, die ich habe, die dies tut:

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

Was die Lösung von HappyEngineer angeht, war es meiner Meinung nach eine ähnliche Problemumgehung, den Versatz "Fortschritt" manuell festzulegen. In beiden Fällen sollte der obige Code für Sie funktionieren.


Danke ... das funktioniert in der Tat ... aber da mein Drawable statisch war (aus Ressourcen) ... hat es nicht funktioniert. Es hat nur funktioniert, nachdem ich "drawable.invalidateSelf ()" hinzugefügt habe. vor dem 'setProgress (0)' und 'setProgressDrawable (drawable)'
Alécio Carvalho


5

Verwenden Sie einfach:

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

Für eine horizontale ProgressBar verwende ich:

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

Ein Beispielaufruf wäre:

  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

Wenn Sie den 'sekundären Fortschritt' nicht benötigen, setzen Sie einfach value2 auf value1.


4

Wenden Sie diesen benutzerdefinierten Stil auf den Fortschrittsbalken an.

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

Verwenden Sie diesen Bildtyp für den Fortschrittsbalken. Geben Sie hier die Bildbeschreibung ein

Für ein besseres Ergebnis können Sie mehrere Fortschrittsbilder verwenden. Und bitte zögern Sie nicht, Bilder zu verwenden, da die Android-Plattform selbst Bilder für die Fortschrittsanzeige verwendet. Der Code wird aus sdk extrahiert :)


4

Gemäß Muhammad-Adil, vorgeschlagen für SDK Version 21 und höher

android:indeterminateTint="@color/orange"

in XML funktioniert für mich, ist einfach genug.


Wenn Sie Änderungen für die gesamte App vornehmen möchten, ändern Sie bitte den Wert von <color name = "RedAccent"> # FE6C27 </ color>. in Ihren Werten / Farben.xml.
Mughil

4

Hier ist der Code zum programmgesteuerten Ändern der Farbe von ProgressBar.

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

Genial. Schnelle und effektive Lösung. Vielen Dank!
Tobias Reich
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.