Jak zmienić kolor paska postępu w Androidzie

473

Korzystam z poziomego paska postępu w mojej aplikacji na Androida i chcę zmienić jego kolor postępu (domyślnie żółty). Jak mogę to zrobić przy użyciu code(nie XML)?

WhiteTigerK
źródło
Czy próbowałeś MyProgressBar.setProgressDrawable (Drawable d), określając mapę bitową o żądanym kolorze? developer.android.com/reference/android/widget/… developer.android.com/reference/android/graphics/drawable/…
fupsduck
2
Tak, próbowałem, ale to nie działa. Ustawia kolor tła całego widoku paska postępu zamiast ustawiać kolor tła tylko samego paska. Dzięki.
WhiteTigerK
21
android:indeterminateTint="@android:color/white"działa tylko na API> = 21
Madeyedexter

Odpowiedzi:

290

Przykro mi, że to nie jest odpowiedź, ale co powoduje, że wymaganie jest ustawione na podstawie kodu? I .setProgressDrawablepowinien działać, jeśli jest poprawnie zdefiniowany

<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>
Alex Volovoy
źródło
4
Powodem jest to, że tworzę pasek postępu dynamicznie i ustawiam jego kolor na żądanie użytkownika. Ponieważ zwykle używam kodu do budowy ekranu GUI i komponentów, nie znam załączonego pliku XML i nie wiem, co to jest lista warstw (choć domyślam się, że budujesz pasek postępu na podstawie kilku warstw ..). W przypadku, gdy chcę użyć załączonego pliku XML - gdzie mam go umieścić w folderze projektu i czy jest coś jeszcze, co muszę zrobić, aby utworzyć pasek postępu na podstawie ustawień XML? Dzięki.
WhiteTigerK
1
Zapisujesz ten plik xml jako plik i umieszczasz go w folderze do rysowania (powiedzmy my_progress.xml) niż ustawiasz go jako plik do rysowania w MyProgressBar.setProgressDrawable () Aby zmienić kolory - musisz zmienić te wartości w @ color / progress_start @ color / progress_end Zasadniczo jest to gradient, w którym można umieścić szesnastkę.
Alex Volovoy
3
Uwaga - plik jest kopią tego, który jest w SDK. Upuściłem tutaj prawa autorskie. Jeśli zajrzysz do folderu res / drawable, zobaczysz dokładnie to, co opublikowałem - kolory są ustawione na żółty gradient zamiast kolorów niestandardowych.
Alex Volovoy
7
Nie pokazuje mi żadnej zmiany koloru. proszę podać kolor, który się sprawdził.
Praveen,
Cześć Alex, twoje odpowiedzi są bardzo miłe. ale próbuję zmienić niestandardowy kolor koła postępu w czasie wykonywania. ale nie mogłem. pomóż mi rozwiązać mój problem .. po osiągnięciu postępu 100%, wtedy zmień kolor i rozpocznij postęp ..
pobieram
485

W przypadku poziomego paska postępu możesz również użyć ColorFilternastępującego:

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

Czerwony pasek postępu za pomocą filtra kolorów

Uwaga: Zmienia to wygląd wszystkich pasków postępu w Twojej aplikacji. Aby zmodyfikować tylko jeden konkretny pasek postępu, wykonaj następujące czynności:

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

Jeśli progressBar jest nieokreślony, użyj getIndeterminateDrawable()zamiastgetProgressDrawable() .

Od wersji Lollipop (API 21) można ustawić odcień postępu:

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

Czerwony pasek postępu za pomocą odcienia postępu

Torben Kohlmeier
źródło
7
Chciałem użyć tej odpowiedzi, ponieważ wydawało mi się to najprostsze, ale mój pasek postępu jest całkowicie czerwony niezależnie od wartości postępu. Czy jesteś pewien, którego trybu będziesz używać?
LG
33
@resus Mam ten sam problem, pasek był w pełni czerwony i nie było widocznego postępu. Ale rozwiązałem go zmieniając Mode.SRC_IN na Mode.MULTIPLY.
Derzu
40
Nie zapomnij zrobić tego samego, getIndeterminateDrawablejeśli używasz nieokreślonego postępu.
Thommy
6
Pamiętaj, że „Tryb” w tym kontekście odnosi się do android.graphics.PorterDuff.Mode
1owk3y
9
jak nie zmieniać koloru tła? Chcę tylko zmienić kolor postępu.
kangear
364

Nie jest to programowo, ale myślę, że i tak mogłoby pomóc wielu ludziom.
Dużo próbowałem i najskuteczniejszym sposobem było dodanie tych wierszy do paska postępu w pliku .xml:

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

W końcu ten kod zrobił to dla mnie:

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

To rozwiązanie działa dla API 21+

F.Firmenich
źródło
45
Wymaga minimalnego poziomu API 21
Apfelsaft
Istnieją również metody ustawiające dla tych właściwości, które można wywołać, jeśli trzeba ustawić dynamiczny kolor.
ściga się
Czy muszę utworzyć niestandardowy plik zasobów dla interfejsu API 21+ i interfejsu API <= 20? Czy te atrybuty są po prostu ignorowane w api <= 20?
prom85
1
@shriduttkothari jak to może być najlepsze? ... od 21+
25
2
Najlepsza odpowiedź, gdy Android odchodzi od minimum 4.x
Tom
229

Dla mojego nieokreślonego paska postępu (pokrętła) po prostu ustawiłem filtr kolorów na rysunku. Działa świetnie i tylko jedna linia.

Przykład, w którym ustawienie koloru na czerwony:

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

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

wprowadź opis zdjęcia tutaj

jhavatar
źródło
16
Najbardziej podoba mi się twoja odpowiedź. Aby mój działał, musiałem to zrobić: myProgressBarSpinner.getIndeterminateDrawable (). SetColorFilter (new LightingColorFilter (0xFF000000, foregroundColorDesired));
Art Geigel
4
Pamiętaj też, że zrobienie tego zmodyfikuje drawables WSZYSTKICH pasków postępu w Twojej aplikacji. Aby to zrobić tylko dla konkretnego, wywołaj mutate () na drawable, następnie ustaw na nim filtr kolorów, a następnie wywołaj setIntederminateDrawable na pasku postępu.
dimsuz
3
NB: Ci, którzy tego używają i zastanawiają się, dlaczego ich kolor nie wygląda dokładnie tak, jak włożyli szesnastkowy sznurek, mają na sobie filtr wielu kolorów. Zmień android.graphics.PorterDuff.Mode.MULTIPLYna, PorterDuff.Mode.SRC_INa otrzymasz dokładny kolor heksadecymalny.
micnguyen,
Myślę, że po prostu potrzebuje tej odpowiedzi ..... android: indeterminateTint = "@ android: color / black"
Muhammad Adil
4
użyłem jako: progressBar = (ProgressBar) findViewById (R.id.progressBar); progressBar.getIndeterminateDrawable (). setColorFilter (ContextCompat.getColor (this, android.R.color.white), android.graphics.PorterDuff.Mode.MULTIPLY);
ashishdhiman2007
188

To stare pytanie, ale użycie motywu nie jest tutaj wymienione. Jeśli używasz domyślnego motywu AppCompat, ProgressBarkolor będzie taki colorAccent, jak zdefiniowałeś.

Zmiana colorAccentspowoduje również zmianę ProgressBarkoloru twojego koloru, ale zmiany te odzwierciedlają się również w wielu miejscach. Jeśli więc chcesz inny kolor tylko dla określonego, PregressBarmożesz to zrobić, stosując do tego motyw ProgressBar:

  • Rozszerz domyślny motyw i zastąp colorAccent

    <style name="AppTheme.WhiteAccent">
        <item name="colorAccent">@color/white</item> <!-- Whatever color you want-->
    </style>
  • I ProgressBardodaj android:themeatrybut:

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

Będzie to wyglądać mniej więcej tak:

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

Więc po prostu zmieniasz colorAccentna swój ProgressBar.

Uwaga : korzystanie stylenie będzie działać. Musisz android:themetylko użyć . Więcej zastosowań motywu znajdziesz tutaj: https://plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH

kirtan403
źródło
18
Wreszcie! dzięki, wygląda na to, że niewielu programistów używa AppCompat, wielu użytkowników po prostu głosuje odpowiedzi z rozwiązaniem dla API 21+, wcale nie jest dobre, powinni obsługiwać więcej urządzeń / systemów operacyjnych, jak to możliwe
25
1
Niesamowite! Pracowałem dla mnie, ale musiałem upewnić się, że gdzieś w hierarchii stylów był rodzic = "@ style / Theme.AppCompat", miałem innego rodzica i na początku nie działało.
Nublodeveloper
@Nublodeveloper Tak Wspomniałem o tym w pierwszym wierszu, jeśli zauważyłeś.
kirtan403
1
@ kirtan403 Ach, tak, rozumiem teraz, kiedy o tym wspominasz, ale nie zrozumiałem tego w ten sposób, kiedy po raz pierwszy przeczytałem. Przeczytałem to zbyt szybko i szukałem kodu. Dzięki, twoja odpowiedź jest dla mnie najlepsza!
Nublodeveloper
+1 Podobało Ci się twoje rozwiązanie. Ale jak ustawić kolor motywu w Javie ??? Na przykład, jeśli chcę, aby był czerwony <color name = "red"> # ff5900 </color>
Maseed
54

Wszystkie API

jeśli używasz wszystkich API, po prostu stwórz stylowo styl

style.xml

<resources>

    //...

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

</resources>

i wykorzystanie w toku

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

Poziom API 21 i wyższy

jeśli jest używany na poziomie API 21 i wyższym, wystarczy użyć tego kodu:

<ProgressBar
   //...
   android:indeterminate="true"
   android:indeterminateTintMode="src_atop"
   android:indeterminateTint="@color/secondary"/>
Rasoul Miri
źródło
1
Fajnie, myślę, że metoda style.xml jest najlepsza. (Nie trzeba powyżej 20 api)
iamkdblue,
1
Najlepsze rozwiązanie, jeśli chcesz jedno rozwiązanie dla wszystkich interfejsów API Dzięki :)
Naveen
34

zgodnie z niektórymi sugestiami, MOŻESZ określić kolor i rysować kolorem, a następnie ustawić go. Mam to programowo. Tak to robię ..

Najpierw upewnij się, że importujesz bibliotekę do rysowania.

import android.graphics.drawable.*;

Następnie użyj kodu podobnego do poniższego;

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);
PaulieG
źródło
1
Próbowałem powyższego kodu, niestety po prostu powoduje to „pusty” pasek postępu. Czy coś brakuje?
OceanBlue
Musisz wywołać setLevel na ClipDrawable. Przyjmuje wartość od 0 do 10000. Zatem progress.setLevel (2500) byłby zapełniony w 25%.
HappyEngineer,
1
Przesłałem poprawkę do odpowiedzi, która wyjaśnia jeden powód „pustego” paska postępu - i 2 sposoby, aby to naprawić (w tym poprawkę @ HappyEngineer)
Richard Le Mesurier
@RichardLeMesurier czy możesz zamieścić wyjaśnienie + 2 sposoby w sekcji komentarzy? progress.setLevel(2500)nie działa dla mnie i prawdopodobnie z jakiegoś powodu Twoja edycja nie została zaakceptowana. Dzięki. +1.
ateiob
@ateiob Napisałem nową odpowiedź, aby wyjaśnić ...
Richard Le Mesurier,
32

To działało dla mnie:

<ProgressBar
 android:indeterminateTint="#d60909"
 ... />
MOH3N
źródło
12
Używany tylko w interfejsie API na poziomie 21 i wyższym
Numair
28

jeśli nieokreślony:

((ProgressBar)findViewById(R.id.progressBar))
    .getIndeterminateDrawable()
    .setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
nóż
źródło
Użyłem tego, ale nie animuje, po prostu zastosowano kolor ... Używam okrągłego
paska
24

To działa dla mnie. Działa również w niższej wersji. Dodaj to do swojego syles.xml

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

I użyj tego w ten sposób w XML

<ProgressBar
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:theme="@style/ProgressBarTheme"
   />
Devinder Jhinjer
źródło
Zaimplementowałem to w przykładowej aplikacji CryptoTweets . Odkryłem, że motyw nadrzędny nie jest wymagany, aby to rozwiązanie działało zgodnie z oczekiwaniami. parent="ThemeOverlay.AppCompat.Light"
Adam Hurwitz
23

Obecnie w 2016 roku zauważyłem, że niektóre urządzenia sprzed wersji Lollipop nie honorują tego colorAccentustawienia, więc moje ostateczne rozwiązanie dla wszystkich interfejsów API jest teraz następujące:

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

W przypadku punktów bonusowych nie używa on przestarzałego kodu. Spróbuj!

Henrique de Sousa
źródło
Nie zapomnij zadzwonić wrapDrawable.mutate()zDrawableCompat.setTint(wrapDrawable.mutate(), ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
Tarsem Singh
Nie działa na Androidzie KitKat 4.4.2.
pradip tilala
Właśnie wypróbowałem (ponownie) na nowym emulatorze 4.4.2 i działa bez żadnych problemów, sprawdź .xmlustawienia, a także, jeśli coś innego przesłania ProgressBarkolor.
Henrique de Sousa
20

Oto co zrobiłem. Pracował

Pasek postępu:

<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:
Tutaj użyj gradientu, aby zmienić kolor, jak chcesz. Android: toDegrees = "X" zwiększa wartość X, a pasek postępu szybko się obraca. Zmniejszaj i obraca się powoli. Dostosuj do swoich potrzeb.

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

próba: wprowadź opis zdjęcia tutaj

Debasish Ghosh
źródło
To pokazuje zupełnie inną (źle wyglądającą) animację niż domyślna.
Ixx
18

Uderz ten sam problem podczas pracy nad modyfikacją wyglądu / działania domyślnego paska postępu. Oto kilka informacji, które, mam nadzieję, pomogą ludziom :)

  • Nazwa pliku xml musi zawierać tylko znaki: a-z0-9_.(tzn. Bez wielkich liter!)
  • Odwołuje się do twojego „wyciągalnego” R.drawable.filename
  • Aby zastąpić domyślny wygląd, użyj myProgressBar.setProgressDrawable(...), jednak nie możesz po prostu odwoływać się do niestandardowego układu jakoR.drawable.filename musisz go pobrać jako Drawable:
    Resources res = getResources();
    myProgressBar.setProgressDrawable(res.getDrawable(R.drawable.filename);
  • Musisz ustawić styl przed ustawieniem postępu / wtórnego postępu / maksimum (ustawienie go później dla mnie skutkowało „pustym” paskiem postępu)
pyko
źródło
15

Prawdopodobnie jest jedna rzecz, o której nie wspomniano w tej odpowiedzi:

Jeśli Twój motyw dziedziczy Theme.AppCompat, ProgressBarprzyjmie kolor zdefiniowany jako"colorAccent" w motywie.

Więc używając…

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

.. odbarwi automatycznie pasek ProgressBar do @color/custom_color.

Henrique de Sousa
źródło
1
Musiałem użyć <item name = "android: colorAccent"> @ color / highlight </item>
tonisives
15
android:progressTint="#ffffff" 
Paweł
źródło
15

Możesz spróbować zmienić swoje style, motywy lub za pomocą Androida: indeterminateTint = "@ color / yourColor" gdziekolwiek chcesz, ale jest tylko jeden sposób, aby to zrobić w dowolnej wersji SKD na Androida:

Jeśli pasek postępu nie jest nieokreślony, użyj:

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

Jeśli pasek postępu jest nieokreślony, użyj:

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

To smutne, że Android to taki bałagan!

Adriano Moutinho
źródło
Dzięki! Działa dla nieokreślonego ProgressBar, ale dla określenia maluje całą skalę kolorem.
CoolMind,
14

Jak to zrobiłem w poziomym pasku postępu:

    LayerDrawable layerDrawable = (LayerDrawable) progressBar.getProgressDrawable();
    Drawable progressDrawable = layerDrawable.findDrawableByLayerId(android.R.id.progress);
    progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
mieszk3
źródło
2
Zrobiłem to samo oraz zmianę koloru tła: layerDrawable.findDrawableByLayerId (android.R.id.background) .setColorFilter (trackColor, PorterDuff.Mode.SRC);
Kamen Dobrev
1
Ta odpowiedź wraz z komentarzem @KamenDobrev jest jedyną, która faktycznie zrobiła to, co chciałem. Gdy tylko ustawię filtr kolorów na rysowalny, zmienia się również kolor tła.
m_katsifarakis,
13

Najprostsze rozwiązanie, jeśli chcesz zmienić kolor w pliku xml układu, użyj poniższego kodu i użyj właściwości indeterminateTint dla żądanego koloru.

    <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" />
Naveed Ahmad
źródło
12

To rozwiązanie działało dla mnie:

<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"/>
S.Javed
źródło
8

Jeszcze jedna drobna rzecz: rozwiązanie motywu działa, jeśli odziedziczysz motyw podstawowy, więc w przypadku aplikacji kompaktowej motyw powinien wyglądać następująco:

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

A następnie ustaw to w motywie paska postępu

<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"/>
Calin
źródło
7

Aby zmienić poziomy pasek ProgressBar (w 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)
    }
}

Aby zmienić nieokreślony kolor paska postępu:

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

I w końcu zwykle zabarwia paski postępu przed Lollipopem

podbarwiony postęp w interfejsie API 19

Jan
źródło
6

Styl niestandardowy poziomy pasek postępu:

Aby zmienić kolor tła i postęp poziomego paska postępu.

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

Zastosuj go do paska postępu, ustawiając atrybut stylu, dla niestandardowych stylów materiałów i niestandardowego paska postępu sprawdź http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples

Arnav Rao
źródło
3
wymaga to minimalnego poziomu API 21
Shihab Uddin
6

Wysłano, aby dodać informacje o odpowiedzi PaulieG, ponieważ ateiob poprosił mnie o wyjaśnienie czegoś ...


Mogę powiedzieć, że w momencie pisania, gdy patrzyłem na obecną wersję kodu źródłowego Androida, był (a przynajmniej był) błąd / problem / optymalizacja w ProgressBarkodzie, który ignoruje próbę ustawienia postępu na wartość jest już na.

  • tzn. jeśli progress = 45 i spróbujesz ustawić go na 45, kod nic nie zrobi i nie przerysuje postępu .

Po telefonowaniu ProgressBar.setProgressDrawable() pasek postępu będzie pusty (ponieważ zmieniłeś część do rysowania).

Oznacza to, że musisz ustawić postęp i przerysować go. Ale jeśli ustawisz postęp na zachowaną wartość, nic to nie da.

Musisz najpierw ustawić na 0, a następnie ponownie na „starą” wartość, a pasek zostanie przerysowany.


Podsumowując:

  • zachowaj „starą” wartość postępu
  • zaktualizuj rysunek / kolor (powoduje, że pasek jest pusty)
  • zresetuj postęp do 0 (w przeciwnym razie następny wiersz nic nie robi)
  • zresetuj postęp do „starej” wartości (pasek poprawek)
  • unieważnić

Poniżej mam metodę, która to robi:

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

Jeśli chodzi o rozwiązanie HappyEngineer, myślę, że podobne obejście polegało na ręcznym ustawieniu przesunięcia „postępu”. W obu przypadkach powyższy kod powinien działać dla Ciebie.

Richard Le Mesurier
źródło
Dzięki .. to działa rzeczywiście .. ale ponieważ mój system rysowania był statyczny (z zasobów) .. to nie działało. Działa to dopiero po dodaniu „drawable.invalidateSelf ();” przed „setProgress (0)” i „setProgressDrawable (drawable)”
Alécio Carvalho
5

Użyj android.support.v4.graphics.drawable.DrawableCompat :

            Drawable progressDrawable = progressBar.getIndeterminateDrawable();
            if (progressDrawable  != null) {
                Drawable mutateDrawable = progressDrawable.mutate();
                DrawableCompat.setTint(mutateDrawable, primaryColor);
                progressBar.setProgressDrawable(mutateDrawable);
            }
Alécio Carvalho
źródło
5

po prostu użyj:

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);
}
Mohammad Fneish
źródło
4

Do poziomego stylu ProgressBar używam:

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

Przykładem wywołania byłoby:

  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

Jeśli nie potrzebujesz „wtórnego postępu”, po prostu ustaw wartość 2 na wartość 1.

Keith
źródło
4

Zastosuj ten niestandardowy styl do paska postępu.

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

Użyj tego typu obrazu jako paska postępu. wprowadź opis zdjęcia tutaj

Aby uzyskać lepszy wynik, możesz użyć wielu obrazów postępu. I nie wahaj się przy użyciu obrazów, ponieważ sama platforma Android używa obrazów na pasku postępu. Kod jest pobierany z SDK :)

Neo
źródło
4

Zgodnie z sugestią Mahometa-Adila dla SDK wer. 21 i nowszych

android:indeterminateTint="@color/orange"

w XML Działa dla mnie, jest dość łatwe.

Mughil
źródło
Jeśli chcesz zmienić dla całej aplikacji, zmień wartość <color name = "RedAccent"> # FE6C27 </color>. w pliku Values ​​/ colors.xml.
mughil
4

Oto kod służący do zmiany koloru paska postępu w sposób programowy.

ProgressBar progressBar = (ProgressBar) findViewById(R.id.pb_listProgressBar);
int colorCodeDark = Color.parseColor("#F44336");
progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorCodeDark));
Naveen Kumar M.
źródło
4
ProgressBar freeRamPb = findViewById(R.id.free_ram_progress_bar);

freeRamPb.getProgressDrawable().setColorFilter(
Color.BLUE, android.graphics.PorterDuff.Mode.SRC_IN);
Wyjątek wskaźnika zerowego
źródło
Niesamowite. Szybkie i skuteczne rozwiązanie. Dzięki!
Tobias Reich