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)?
android:indeterminateTint="@android:color/white"działa tylko na API> = 21
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)?
android:indeterminateTint="@android:color/white"działa tylko na API> = 21
Odpowiedzi:
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>
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);
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));
getIndeterminateDrawablejeśli używasz nieokreślonego postępu.
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+
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);

android.graphics.PorterDuff.Mode.MULTIPLYna, PorterDuff.Mode.SRC_INa otrzymasz dokładny kolor heksadecymalny.
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
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"/>
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);
progress.setLevel(2500)nie działa dla mnie i prawdopodobnie z jakiegoś powodu Twoja edycja nie została zaakceptowana. Dzięki. +1.
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"
/>
parent="ThemeOverlay.AppCompat.Light"
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!
wrapDrawable.mutate()zDrawableCompat.setTint(wrapDrawable.mutate(), ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
.xmlustawienia, a także, jeśli coś innego przesłania ProgressBarkolor.
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>
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 :)
a-z0-9_.(tzn. Bez wielkich liter!)R.drawable.filenamemyProgressBar.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); 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.
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!
ProgressBar, ale dla określenia maluje całą skalę kolorem.
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);
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" />
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"/>
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"/>
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
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
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.
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:
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.
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);
}
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);
}
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.
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.

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 :)
Zgodnie z sugestią Mahometa-Adila dla SDK wer. 21 i nowszych
android:indeterminateTint="@color/orange"
w XML Działa dla mnie, jest dość łatwe.
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));
ProgressBar freeRamPb = findViewById(R.id.free_ram_progress_bar);
freeRamPb.getProgressDrawable().setColorFilter(
Color.BLUE, android.graphics.PorterDuff.Mode.SRC_IN);