Comment changer la couleur de l'indicateur de progression de ProgressBar dans Android

178

J'ai mis Horizontal ProgressBar.

Je voudrais changer la couleur de progression en jaune.

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

Le problème est que la couleur de progression est différente selon les appareils. Donc, je veux qu'il corrige la couleur de progression.

Nishant Shah
la source
Les réponses ci-dessus changent toute la couleur d'arrière-plan et il est ambigu que la hauteur de la barre de progression soit très maximale, ce qui ne peut pas changer en xml. meilleure façon de changer uniquement l'état de la barre de progression dont la quantité est de 20% de couleur rouge, 50% de couleur jaune à 70% et plus de couleur verte. vous pouvez le faire par programme en java. partagez votre réponse si vous avez une autre solution.
Mubashar

Réponses:

365

J'ai copié ceci à partir de l'une de mes applications, il y a donc quelques attributs supplémentaires, mais cela devrait vous donner une idée. Ceci provient de la mise en page qui a la barre de progression:

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

Ensuite, créez un nouveau dessinable avec quelque chose de similaire à ce qui suit (dans ce cas 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>

Vous pouvez changer les couleurs selon vos besoins, cela vous donnera une barre de progression verte.

Ryan
la source
Et aussi je supprime cet androïde: indeterminate = "false"
Nishant Shah
2
Aidez-moi, s'il vous plaît. J'essaie de créer greenprogress.xml en copiant votre code mais la marque Android Studio 0.4.6 <layer-list> comme et l'erreur "La liste des éléments doit être déclarée" que dois-je faire?
UmAnusorn
1
Est-il possible de changer la couleur de manière dynamique?
async
la couleur peut-elle être modifiée en fonction de la valeur de progression actuelle définie dans la barre réelle?
Jonathan
@Ryan Il serait utile d'expliquer ce que android:id="@android:id/progress", android:id="@android:id/background"et android:id="@android:id/secondaryProgress"défendre.
RustamG
103

Une solution plus simple:

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
la source
1
here @ color / disabled est une couleur personnalisée
Nitin Saxena
2
Ou <solid android: color = "@ android: color / black" />, ou même <solid android: color = "# ff33b5e5" />
superarts.org
2
C'est assez android: indeterminateTint = "@ color / white" pour API lever 21 et au
Ghanshyam Nayma
53

Créez simplement un style values/styles.xml.

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

Ensuite, définissez ce style comme ProgressBarthème.

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

et peu importe, votre barre de progression est horizontale ou circulaire. C'est tout.

Ali Zeynali
la source
1
Wow, la solution la plus simple, fonctionne pour moi. Je me suis demandé pourquoi cette réponse avait autant de voix.
Pavel Shorokhov
38

Si vous souhaitez uniquement modifier la couleur de la barre de progression, vous pouvez simplement utiliser un filtre de couleur dans la méthode onCreate () de votre activité:

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

Idée d' ici .

Vous n'avez besoin de le faire que pour les versions pré-sucette. Sur Lollipop, vous pouvez utiliser l'attribut de style colorAccent.

amfcosta
la source
Pour SeekBarc'est le même, il suffit d' ajouter de l' API 16: seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);. Cela changera la couleur de ce pouce rond.
Sufian
1
setColorFilter()Faire appel à un dessin directement appliquera la couleur partout. Puisque c'est ce dont je n'avais pas besoin, je viens d'appeler mutate()le Drawable(c'est-à-dire commeseekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Sufian
3
J'ai vu cette solution ailleurs, mais tout ce qu'elle fait (test sur un appareil Gingerbread) est de tourner toute la barre de progression d'une couleur, ce qui rend impossible de voir les progrès réels
Neil C.Obremski
@ NeilC.Obremski oui vous avez raison. Cela peut être spécifique à la ROM, ou peut-être spécifique à la version. J'ai dû l'enlever complètement. J'espère que nous aurons bientôt cela porté vers les anciennes versions d'Android (via support lib).
Sufian
25

pour le niveau d'API 21 ou supérieur, utilisez simplement

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

Il y a 3 façons de résoudre cette question:

  1. Comment ajuster la couleur de la barre de progression de manière déclarative
  2. Comment ajuster la couleur de la barre de progression par programme, mais choisir la couleur parmi diverses couleurs prédéterminées déclarées avant la compilation
  3. Comment ajuster la couleur de la barre de progression par programme et créer également la couleur par programme.

En particulier, il y a beaucoup de confusion autour des # 2 et # 3, comme on le voit dans les commentaires à la réponse de l'amfcosta. Cette réponse donnera des résultats de couleur imprévisibles chaque fois que vous souhaitez définir la barre de progression sur autre chose que les couleurs primaires, car elle ne modifie que la couleur d'arrière-plan, et la zone de «clip» de la barre de progression réelle sera toujours une superposition jaune avec une opacité réduite. Par exemple, l'utilisation de cette méthode pour définir l'arrière-plan en violet foncé entraînera une couleur de "clip" de la barre de progression d'une couleur rose folle résultant d'un mélange de violet foncé et de jaune via un alpha réduit.

Donc de toute façon, Ryan répond parfaitement au n ° 1 et Štarke répond à la plupart des n ° 3, mais pour ceux qui recherchent une solution complète aux n ° 2 et 3:


Comment ajuster la couleur de la barre de progression par programme, mais choisir la couleur à partir d'une couleur prédéterminée déclarée en XML

res / drawable / my_progressbar.xml :

Créez ce fichier mais changez les couleurs dans my_progress et my_secondsProgress:

(REMARQUE: il ne s'agit que d'une copie du fichier XML réel définissant la barre de progression du SDK Android par défaut, mais j'ai changé les identifiants et les couleurs. L'original est nommé 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>

Dans votre 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)

Comment ajuster la couleur de la barre de progression par programme et créer également la couleur par programme

EDIT: j'ai trouvé le temps de résoudre ce problème correctement. Ma réponse précédente laissait cela un peu ambigu.

Un ProgressBar est composé de 3 Drawables dans un LayerDrawable.

  1. La couche 1 est l'arrière-plan
  2. La couche 2 est la couleur de progression secondaire
  3. La couche 3 est la principale couleur de la barre de progression

Dans l'exemple ci-dessous, je changerai la couleur de la barre de progression principale en cyan.

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

Cet exemple lui attribue une couleur unie. Vous pouvez le définir sur une couleur dégradée en remplaçant

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

avec

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

À votre santé.

-Lance

lance.dolan
la source
qu'est-ce que viewUtils dans viewUtils.convertDpToPixel (5);
Nikos Hidalgo du
1
Salut @NikosHidalgo - Vous pouvez voir une méthode presque identique ici: stackoverflow.com/questions/12849366/… . La seule différence est que je construis mon ViewUtilsavec une référence à Context, de sorte que je n'ai pas besoin de passer un Contextlors de l'appelconvertDpToPixel()
lance.dolan
Merci pour votre réponse rapide, en particulier sur une réponse postée il y a si longtemps!
Nikos Hidalgo du
Haha, j'ai vraiment dû étirer mon cerveau pour me souvenir: p
lance.dolan
4

Si vous êtes au niveau d'API 21 ou supérieur, vous pouvez utiliser ces attributs XML:

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

La solution la plus simple que j'ai découverte est quelque chose comme ceci:

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

Mettez ce qui précède dans le styles.xmlfichier sous le res > valuesdossier.

REMARQUE: Si vous utilisez une autre couleur d'accentuation, les solutions précédentes devraient être adaptées.

API 21 ou SUPÉRIEUR

Sazid
la source
C'est la meilleure solution. 100% lié à la question posée. very simple
Pir Fahim Shah
3
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.getDrawable(2).setColorFilter(color,PorterDuff.Mode.SRC_IN);
user3135773
la source
1
Essayez d'ajouter une petite explication à votre réponse. Les réponses au code uniquement sont déconseillées.
Alexei le
J'adorerais avoir une explication derrière l'index 2 dans getDrawable, mais au moins c'était la seule solution qui a fonctionné pour moi, alors merci!
Nikos Hidalgo du
2

Pour tous ceux qui recherchent comment le faire par programme:

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

La définition des identifiants sur les drawables est cruciale et prend soin de préserver les limites et l'état réel de la barre de progression

Štarke
la source
1

Vous me donnez vraiment mal à la tête. Ce que vous pouvez faire est de rendre d'abord votre liste de calques dessinable via xml (ce qui signifie un arrière-plan comme premier calque, un dessinable qui représente la progression secondaire en tant que deuxième calque, et un autre dessinable qui représente la progression principale en tant que dernier calque), puis changez la couleur sur le code en procédant comme suit:

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

Cette méthode vous donnera la meilleure flexibilité d'avoir la mesure de votre dessinable original déclaré sur le xml, SANS MODIFICATION DE SA STRUCTURE APRÈS, surtout si vous avez besoin d'avoir le dossier d'écran du fichier xml spécifique, puis en modifiant UNIQUEMENT LA COULEUR via le code. Pas de ré-instanciation d'un nouveau ShapeDrawable à partir de zéro.

Jetée Betos
la source
1

La couleur ProgressBar peut être modifiée comme suit:

/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
la source
1

Créez une ressource dessinable de quel arrière-plan vous avez besoin, dans mon cas, je l'ai nommé bg_custom_progressbar.xml

<?xml version="1.0" encoding="utf-8"?>

<item>
    <shape android:shape="rectangle" >
        <corners android:radius="5dp"/>

        <gradient
            android:angle="180"
            android:endColor="#DADFD6"
            android:startColor="#AEB9A3" />
    </shape>
</item>
<item>
    <clip>
        <shape android:shape="rectangle" >
            <corners android:radius="5dp" />

            <gradient
                android:angle="180"
                android:endColor="#44CF4A"
                android:startColor="#2BB930" />
        </shape>
    </clip>
</item>
<item>
    <clip>
        <shape android:shape="rectangle" >
            <corners android:radius="5dp" />

            <gradient
                android:angle="180"
                android:endColor="#44CF4A"
                android:startColor="#2BB930" />
        </shape>
    </clip>
</item>

Ensuite, utilisez cet arrière-plan personnalisé comme

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

Ça marche bien pour moi

Md Juyel Rana
la source
0

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

VoirModèle:

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
la source
0

Avec la bibliothèque de composants de matériaux, vous pouvez utiliser ProgressIndicatoravec l' app:indicatorColorattribut pour changer la couleur:

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

entrez la description de l'image ici

Remarque : il nécessite au moins la version 1.3.0-alpha01.

Avec le, ProgressBarvous pouvez remplacer la couleur en utilisant:

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

avec:

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

entrez la description de l'image ici

Gabriele Mariotti
la source
0

Si vous souhaitez définir la couleur de progression principale et secondaire sur la barre de progression horizontale par programme dans Android, utilisez l'extrait ci-dessous

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