Як змінити колір індикатора ходу ProgressBar в Android


178

Я встановив горизонтальний ProgressBar.

Я хотів би змінити колір прогресу на жовтий.

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

Проблема полягає в тому, що колір прогресу у різних пристроїв різний. Отже, я хочу, щоб він фіксував колір прогресу.


вище відповіді змінюють весь колір фону і амбіції - це змінити висоту смуги прогресу на дуже максимум, що не в змозі змінити в xml. кращий спосіб змінити лише статус смуги прогресу: кількість червоних кольорів на 20%, на 50% жовтий на 70% і вище на зелений. ви можете це робити програмно в Java. поділіться своєю відповіддю, якщо у вас є якесь інше рішення.
Мубашар

Відповіді:


365

Я скопіював це з одного з моїх додатків, тому є кілька додаткових атрибутів, але я повинен дати вам ідею. Це з макета, на якому є смужка прогресу:

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

Тоді створіть новий малюнок із чимось подібним до наступного (У цьому випадку 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>

Ви можете змінити кольори за потребою, це дасть вам зелену смугу прогресу.


А також я видаляю цей андроїд: indeterminate = "false"
Nishant Shah

2
Будь ласка, допоможи мені. Я намагаюся створити greenprogress.xml, скопіювавши свій код, але на Android Studio 0.4.6 позначити <layer-list> як і помилку "Список елементів повинен бути оголошений", що мені робити?
UmAnusorn

1
Чи можливо змінити колір динамічно?
async

чи можна змінювати колір залежно від поточного значення прогресу, визначеного у фактичному рядку?
Джонатан

@Ryan Було б корисно , щоб пояснити , що android:id="@android:id/progress", android:id="@android:id/background"і android:id="@android:id/secondaryProgress"стояти.
РустамГ

103

Більш просте рішення:

progess_dravable_blue

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
    <shape>
        <solid
                android:color="@color/disabled" />
    </shape>
</item>

<item
    android:id="@android:id/progress">
    <clip>
        <shape>
            <solid
                android:color="@color/blue" />
        </shape>
    </clip>
</item>

</layer-list>

1
тут @ color / disabled - це власний колір
Nitin Saxena

2
Або <твердий андроїд: color = "@ android: color / black" />, або навіть <solid android: color = "# ff33b5e5" />
superarts.org

2
Цього достатньо для android: indeterminateTint = "@ color / white" для важеля API 21 і вище
Ghanshyam Nayma

53

Просто створіть стиль в values/styles.xml.

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

Потім встановіть цей стиль як свою ProgressBarтему.

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

і не має значення, що ваша смужка ходу - горизонтальна або кругла. Це все.


1
Нічого собі, найпростіше рішення працює для мене. Мені було цікаво, чому ця відповідь має стільки голосів.
Павло Шорохов

38

Якщо ви хочете змінити лише колір смужки прогресу, ви можете просто використовувати фільтр кольорів у методі onCreate () своєї діяльності:

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

Ідея звідси .

Це потрібно робити лише для попередніх льодяників. У Lollipop ви можете використовувати атрибут стилю colorAccent.


Для SeekBarце те ж саме, просто додайте до API 16: seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);. Це змінить колір круглого великого пальця.
Суфіан

1
Якщо натиснути setColorFilter()на малюнок, який можна перетягнути, колір буде застосовано всюди. Оскільки це те , що мені не потрібно, я просто подзвонив mutate()на Drawable(тобто якseekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Sufian

3
Я бачив це рішення в іншому місці, але все, що він робить (тестування на пристрої з пряників) - це перетворити всю панель прогресу на один колір, що робить неможливим бачити фактичний прогрес
Ніл К. Обремський,

@ NeilC.Obremski так, ти маєш рацію. Це може бути специфічно для ROM, а може бути і для версії. Мені довелося її повністю прибрати. Сподіваємось, незабаром ми повернемося до старих версій Android (через підтримку lib).
Суфіан

25

для API рівня 21 або вище просто використовуйте

android:progressBackgroundTint="@color/yourBackgroundColor"
android:progressTint="@color/yourColor"

6

Існує 3 способи вирішити це питання:

  1. Як декларативно налаштувати колір смуги прогресу
  2. Як налаштувати колір смужки прогресу програмно, але вибрати колір із різних заздалегідь визначених кольорів, оголошених до моменту компіляції
  3. Як програмно налаштувати колір панелі прогресу, а також створити колір програмно.

Зокрема, існує велика плутанина навколо №2 та №3, як це видно в коментарях до відповіді amfcosta. Ця відповідь дасть непередбачувані результати кольорів у будь-який час, коли ви хочете встановити панель прогресу на будь-що, крім основних кольорів, оскільки він лише змінює колір фону, а фактична область "кліпу" смужки ходу все ще буде жовтою накладкою зі зменшеною непрозорістю. Наприклад, використання цього методу для встановлення тла на темно-фіолетовий призведе до того, що смужка "кліпу" прогресує кольором якогось божевільного рожевого кольору в результаті змішування темно-фіолетового та жовтого кольору через зменшену альфа.

Тож як ні круто, на відповідь Раян Райан, а Штарке відповідає на більшість №3, але для тих, хто шукає повне рішення №2 та №3:


Як налаштувати колір смужки прогресу програмно, але вибрати колір із заздалегідь визначеного кольору, оголошеного в XML

res / dravable / my_progressbar.xml :

Створіть цей файл, але змініть кольори в my_progress та my_secondsProgress:

(ПРИМІТКА. Це лише копія фактичного файлу XML, що визначає стандартний андроїд SDK ProgressBar, але я змінив ідентифікатори та кольори. Оригінал названий 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>

На вашій 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)

Як програмно налаштувати колір панелі прогресу, а також створити колір програмно

EDIT: Я знайшов час вирішити це правильно. Моя колишня відповідь залишила це трохи неоднозначним.

Програму ProgressBar складають у вигляді 3-х малюнків у шарі Dravavable.

  1. Шар 1 - фон
  2. Шар 2 є кольором вторинного прогресу
  3. Шар 3 - основний колір смужки прогресу

У наведеному нижче прикладі я зміню колір основної смуги прогресу на синій.

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

Цей приклад встановив її суцільний колір. Ви можете встановити його на колір градієнта, замінивши

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

з

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

Ура.

-Звінок


що viewUtils у viewUtils.convertDpToPixel (5);
Нікос Ідальго

1
Привіт @NikosHidalgo - Ви можете побачити майже однаковий метод тут: stackoverflow.com/questions/12849366/… . Єдина відмінність полягає ViewUtilsв Contextтому, що я ContextconvertDpToPixel()
будую

Дякуємо за вашу швидку відповідь, особливо за відповідь, яка була опублікована так давно!
Нікос Ідальго

Ха-ха, мені справді довелося розтягнути мозок, щоб пам’ятати: p
lance.dolan

4

Якщо ви перебуваєте в рівні 21 або вище API, ви можете використовувати ці атрибути XML:

<!-- For indeterminate progress bar -->
android:indeterminateTint="@color/white"
<!-- For normal progress bar -->
android:progressTint="@color/white"

3

Найпростіше рішення, яке я знайшов, є щось подібне:

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

Покладіть вище у styles.xmlфайл під res > valuesпапку.

ПРИМІТКА. Якщо ви використовуєте будь-який інший колір акценту, то попередні рішення повинні бути корисними.

API 21 або ВИЩЕ


Це найкраще рішення. На 100% стосується поставленого питання. дуже просто
Пір Фахім Шах

3
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.getDrawable(2).setColorFilter(color,PorterDuff.Mode.SRC_IN);

1
Спробуйте додати трохи пояснень у свою відповідь. Відповіді з коду відмовляються.
Олексій

Я хотів би отримати пояснення за індексом 2 у getDrawable, але принаймні це було єдине рішення, яке працювало для мене, тож дякую!
Нікос Ідальго

2

Для тих, хто шукає, як це зробити програмно:

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

Встановлення ідентифікаторів для чернетки є надзвичайно важливим, і це забезпечує збереження меж та фактичного стану смуги прогресу


1

Ви, хлопці, справді боліти мені. Що ви можете зробити, це зробити список шарів, який можна малювати спочатку через xml (маючи на увазі фон як перший шар, малюнок, який представляє вторинний прогрес у якості другого шару, та інший рисунок, який представляє первинний прогрес як останній шар), а потім змінити колір у коді, виконуючи наступні дії:

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

Цей метод дасть вам найкращу гнучкість вимірювання оригінального малюваного зображення на xml, БЕЗ МОДИФІКАЦІЇ НА ЇЇ СТРУКТУРІ ПІСЛЯ, особливо якщо вам потрібно мати специфічну папку з файлом xml, а потім просто змінити ТІЛЬКИЙ КОЛЕР код. Ніякого повторного встановлення нового ShapeDravable з нуля.


1

Колір ProgressBar можна змінити наступним чином:

/res/values/colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorAccent">#FF4081</color>
</resources>

/res/values/styles.xml

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

onCreate:

progressBar = (ProgressBar) findViewById(R.id.progressBar);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    Drawable drawable = progressBar.getIndeterminateDrawable().mutate();
    drawable.setColorFilter(ContextCompat.getColor(this, R.color.colorAccent), PorterDuff.Mode.SRC_IN);
    progressBar.setIndeterminateDrawable(drawable);
}

1

Створіть ресурс, який можна отримати, який фон вам потрібен, в моєму випадку я назвав його 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>

Потім використовуйте цей спеціальний фон, як-от

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

Це добре працює для мене


0

У xml:

<ProgressBar
                    android:id="@+id/progressBar"
                    style="?android:attr/progressBarStyleInverse"
                    android:layout_width="60dp"
                    android:layout_height="60dp"
                    android:layout_margin="@dimen/dimen_10dp"


                 android:indeterminateTint="@{viewModel.getComplainStatusUpdate(position)}"
                    android:indeterminate="true"
                    android:indeterminateOnly="false"
                    android:max="100"
                    android:clickable="false"
                    android:indeterminateDrawable="@drawable/round_progress"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

ViewModel:

fun getComplainStatusUpdate(position: Int):Int{

                val list = myAllComplainList!!.getValue()
                if (list!!.get(position).complainStatus.equals("P")) {
                  //  progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
                   // progressBar.setBackgroundResource(R.drawable.circle_shape)
                    return Color.RED
                } else if (list!!.get(position).complainStatus.equals("I")) {

                    return Color.GREEN
                } else {

                    return Color.GREEN
                }


return Color.CYAN
    }

0

З Матеріальні компоненти бібліотеки ви можете використовувати ProgressIndicatorз app:indicatorColorатрибутом , щоб змінити колір:

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

введіть тут опис зображення

Примітка : для цього потрібна принаймні версія 1.3.0-alpha01.

За допомогою ProgressBarви можете змінити колір за допомогою:

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

з:

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

введіть тут опис зображення


0

Якщо ви хочете встановити основний і вторинний колір прогресу на горизонтальній смузі прогресу програмно в андроїді, тоді використовуйте фрагмент нижче

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));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.