Как изменить цвет индикатора выполнения в Android

474

Я использую горизонтальный индикатор выполнения в своем приложении для Android и хочу изменить его цвет выполнения (по умолчанию желтый). Как я могу сделать это с помощью code(не XML)?

WhiteTigerK
источник
Вы пробовали MyProgressBar.setProgressDrawable (Drawable d), указав растровое изображение с нужным цветом? developer.android.com/reference/android/widget/… developer.android.com/reference/android/graphics/drawable/…
fupsduck
2
Да, я пробовал это, но это не работает. Он устанавливает цвет фона всего индикатора выполнения вместо того, чтобы устанавливать цвет фона только самой панели. Спасибо.
WhiteTigerK
21
android:indeterminateTint="@android:color/white"работает только на API> = 21
Madeyedexter

Ответы:

291

Я сожалею, что это не ответ, но что движет требованием, устанавливающим это из кода? И .setProgressDrawableдолжен работать, если он определен правильно

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@android:id/background">
    <shape>
        <corners android:radius="5dip" />
        <gradient
                android:startColor="#ff9d9e9d"
                android:centerColor="#ff5a5d5a"
                android:centerY="0.75"
                android:endColor="#ff747674"
                android:angle="270"
        />
    </shape>
</item>

<item android:id="@android:id/secondaryProgress">
    <clip>
        <shape>
            <corners android:radius="5dip" />
            <gradient
                    android:startColor="#80ffd300"
                    android:centerColor="#80ffb600"
                    android:centerY="0.75"
                    android:endColor="#a0ffcb00"
                    android:angle="270"
            />
        </shape>
    </clip>
</item>

<item android:id="@android:id/progress">
    <clip>
        <shape>
            <corners
                android:radius="5dip" />
            <gradient
                android:startColor="@color/progress_start"
                android:endColor="@color/progress_end"
                android:angle="270" 
            />
        </shape>
    </clip>
</item>

</layer-list>
Алекс Воловой
источник
4
Причина в том, что я динамически создаю индикатор выполнения и устанавливаю его цвет по запросу пользователя. Поскольку я обычно использую код для создания своего экрана графического интерфейса и компонентов, я не знаком с приложенным XML и не знаю, что такое список слоев (хотя я предполагаю, что вы строите индикатор выполнения на основе нескольких слоев ..). В случае, если я хочу использовать прикрепленный вами XML-файл, где я должен поместить его в папку проекта и нужно ли что-то еще сделать для создания индикатора выполнения на основе настроек XML? Спасибо.
WhiteTigerK
1
Вы сохраняете этот XML-файл как файл и помещаете его в папку drawable (скажем, my_progress.xml), а затем устанавливаете его как drawable в MyProgressBar.setProgressDrawable (). Чтобы изменить цвета, вам нужно изменить эти значения в @ color / progress_start @ color / progress_end Это в основном градиент, и вы можете поместить туда гекс.
Алексей Воловой
3
Примечание - файл является копией того, что находится в SDK. Я потерял авторские права здесь. Если вы загляните в папку res / drawable, вы увидите именно то, что я опубликовал - цвета настроены на желтый градиент вместо пользовательских цветов.
Алексей Воловой
7
Это не показывает никакого изменения цвета для меня. пожалуйста, скажите цвет, который сработал.
Правин
Привет Алекс, твои ответы очень хорошие. но я пытался изменить пользовательский цвет колеса прогресса во время выполнения. но я не мог. Пожалуйста, помогите мне решить мою проблему .. после того, как прогресс достигнет 100%, затем измените цвет и начните прогресс .. я загружаю код с этого ... stackoverflow.com/questions/18503718/…
harikrishnan
485

Для горизонтального ProgressBar вы можете использовать ColorFilterтоже, как это:

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

Красный ProgressBar с использованием цветового фильтра

Примечание. Это изменяет внешний вид всех индикаторов выполнения в вашем приложении. Чтобы изменить только один конкретный индикатор выполнения, сделайте это:

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

Если progressBar не определен, используйте getIndeterminateDrawable()вместоgetProgressDrawable() .

Начиная с Lollipop (API 21) вы можете установить оттенок прогресса:

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

Красный ProgressBar с использованием оттенка прогресса

Торбен Кольмайер
источник
7
Я хотел использовать этот ответ, так как он мне показался самым простым, но мой индикатор выполнения полностью красный, независимо от значения прогресса. Вы уверены, что режим использовать?
LG
33
@resus У меня та же проблема, панель была полностью красной и никакого прогресса не было видно. Но я решил это, изменив Mode.SRC_IN на Mode.MULTIPLY.
Derzu
40
Не забудьте сделать то же самое, getIndeterminateDrawableесли вы используете неопределенный прогресс.
Томми
6
Следует помнить, что «Режим» в этом контексте относится к android.graphics.PorterDuff.Mode
1owk3y
9
как не изменить цвет фона? Я просто хочу изменить цвет прогресса.
kangear
364

Это не программно, но я думаю, что это может помочь многим людям в любом случае.
Я много пробовал, и самым эффективным способом было добавить эти строки в мой ProgressBar в файле .xml:

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

В итоге этот код сделал это для меня:

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

Это решение работает для API 21+

FFirmenich
источник
45
Требуется минимальный уровень API 21
Apfelsaft
Для этих свойств также существуют методы установки, которые можно вызывать, если необходимо установить динамический цвет.
racs
Нужно ли мне создавать пользовательский файл ресурсов для api 21+ и api <= 20? Или эти атрибуты просто игнорируются в API <= 20?
Prom85
1
@shriduttkothari как это может быть лучшим? ... это от 21+
user25
2
Лучший ответ, когда Android отходит от минимума 4.х
Том
229

Для моего неопределенного индикатора выполнения (счетчик) я просто установил цветной фильтр на рисование. Отлично работает и всего одна строчка.

Пример установки красного цвета:

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

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

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

jhavatar
источник
16
Мне нравится ваш ответ лучше всего. Для моей работы, хотя я должен был сделать это: myProgressBarSpinner.getIndeterminateDrawable (). SetColorFilter (new LightingColorFilter (0xFF000000, foregroundColorDesired));
Арт Гайгель
4
Также обратите внимание, что это приведет к изменению рисования ВСЕХ индикаторов прогресса в вашем приложении. Чтобы сделать это только для конкретного, вызовите mutate () для drawable, затем установите для него цветной фильтр и затем вызовите setIntederminateDrawable для вашего progressBar.
dimsuz
3
NB: Те, кто использует это и задаются вопросом, почему их цвет не выглядит точно как шестнадцатеричная строка, которую они вставили, у него есть фильтр с несколькими цветами. Измените android.graphics.PorterDuff.Mode.MULTIPLYна PorterDuff.Mode.SRC_INи вы получите точный шестнадцатеричный цвет.
micnguyen
Я думаю, что ему просто нужен этот ответ ..... android: indeterminateTint = "@ android: color / black"
Мухаммед Адил
4
я использовал как: progressBar = (ProgressBar) findViewById (R.id.progressBar); progressBar.getIndeterminateDrawable (). setColorFilter (ContextCompat.getColor (this, android.R.color.white), android.graphics.PorterDuff.Mode.MULTIPLY);
ashishdhiman2007
189

Это старый вопрос, но использование темы здесь не упоминается. Если ваша тема по умолчанию использует AppCompat, ваш ProgressBarцвет будетcolorAccent вы определили.

Изменение colorAccentтакже изменит ваш ProgressBarцвет, но изменения также отражаются в нескольких местах. Итак, если вы хотите другой цвет только для определенного, PregressBarвы можете сделать это, применив тему к этому ProgressBar:

  • Расширьте тему по умолчанию и переопределите colorAccent

    <style name="AppTheme.WhiteAccent">
        <item name="colorAccent">@color/white</item> <!-- Whatever color you want-->
    </style>
  • И ProgressBarдобавьте android:themeатрибут:

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

Так это будет выглядеть примерно так:

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

Таким образом, вы просто меняете colorAccentдля своего конкретного ProgressBar.

Примечание : использование styleне будет работать. Вам нужно использовать android:themeтолько. Вы можете найти больше использования темы здесь: https://plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH

kirtan403
источник
18
наконец-то! спасибо, похоже, что не многие разработчики используют AppCompat, многие пользователи просто голосуют за ответы с помощью решения для API 21+, совсем не хорошо, им следует поддерживать как можно больше устройств / ОС
user25
1
Потрясающие! Работал для меня, но я должен был убедиться, что где-то в иерархии стилей есть parent = "@ style / Theme.AppCompat", у меня был другой родитель, и сначала он не работал.
Nublodeveloper
@Nublodeveloper Да, я упомянул это в первой строке, если вы заметили.
kirtan403
1
@ kirtan403 Ах, да, я понял, теперь вы упомянули об этом, но я не понял этого, когда впервые прочитал. Я прочитал это слишком быстро, и я искал код. В любом случае, спасибо, мой ответ - лучший для меня!
Nublodeveloper
+1 Понравилось ваше решение. А как установить цвет темы в java ??? Например, если я хочу, чтобы он был красным <color name = "red"> # ff5900 </ color>
Maseed
54

Все API

если использовать все API, просто создайте тему в стиле

style.xml

<resources>

    //...

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

</resources>

и использовать в процессе

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

Уровень API 21 и выше

если используется в API уровня 21 и выше, просто используйте этот код:

<ProgressBar
   //...
   android:indeterminate="true"
   android:indeterminateTintMode="src_atop"
   android:indeterminateTint="@color/secondary"/>
Расул Мири
источник
1
Хорошо, я думаю, что метод style.xml - лучший. (Нет необходимости выше 20 api)
iamkdblue
1
Лучшее решение, если вы хотите одно решение для всех API Спасибо :)
Naveen
34

Согласно некоторым предложениям, вы МОЖЕТЕ указать форму и клип-макет с цветом, а затем установить его. У меня это работает программно. Вот как я это делаю ..

Сначала убедитесь, что вы импортируете библиотеку drawable.

import android.graphics.drawable.*;

Затем используйте код, подобный приведенному ниже;

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
источник
1
Я попробовал приведенный выше код, к сожалению, это просто приводит к «пустой» индикатор выполнения. Я что-то пропустил?
OceanBlue
Вам необходимо вызвать setLevel для ClipDrawable. Он принимает значение от 0 до 10000. Таким образом, progress.setLevel (2500) будет заполнен на 25%.
HappyEngineer
1
Я отправил изменение в ответ, в котором объясняется одна из причин «пустого» индикатора выполнения и два способа его исправить (включая исправление HappyEngineer)
Ричард Ле Мезурье,
@RichardLeMesurier вы можете опубликовать объяснение + 2 способа в разделе комментариев? progress.setLevel(2500)у меня не работает и, видимо, по какой-то причине ваше редактирование не было принято. Спасибо. +1.
ateiob
@ateiob Я написал новый ответ, чтобы объяснить ...
Ричард Ле Мезурье
32

Это сработало для меня:

<ProgressBar
 android:indeterminateTint="#d60909"
 ... />
MOH3N
источник
12
Используется только в API уровня 21 и выше
Numair
28

если неопределенный:

((ProgressBar)findViewById(R.id.progressBar))
    .getIndeterminateDrawable()
    .setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
нож
источник
Я использовал это, но это не оживляет, только цвет был применен ... Я использую круговой индикатор выполнения
Manikandan
24

Это работает для меня. Это также работает для более низкой версии тоже. Добавьте это к вашему syles.xml

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

И использовать это в XML

<ProgressBar
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:theme="@style/ProgressBarTheme"
   />
Devinder Jhinjer
источник
Я реализовал это в примере приложения CryptoTweets . Я обнаружил, что родительская тема не требуется для этого решения для работы, как ожидалось. parent="ThemeOverlay.AppCompat.Light"
Адам Гурвиц
23

В настоящее время в 2016 году я обнаружил, что некоторые устройства до Lollipop не соответствуют этим colorAccentнастройкам, поэтому мое окончательное решение для всех API теперь следующее:

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

Для получения бонусных баллов не используется устаревший код. Попробуй это!

Энрике де Соуза
источник
Не забудьте позвонить wrapDrawable.mutate()сDrawableCompat.setTint(wrapDrawable.mutate(), ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
Тарсем Сингх
Не работает на Android KitKat 4.4.2.
Прадип Тилала
Только что попробовал (снова) на новом новом эмуляторе 4.4.2, и он работает без каких-либо проблем, проверьте ваши .xmlнастройки, а также, если что-то переопределяет ProgressBarцвет.
Энрике де Соуза
20

Это то, что я сделал. Работал.

Индикатор:

<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:
здесь используйте градиент, чтобы изменить цвет по своему усмотрению. And android: toDegrees = "X" увеличивает значение X, и индикатор выполнения вращается быстро. Уменьшить и вращать медленно. Настройте в соответствии с вашими потребностями.

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

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

Дебашиш Гош
источник
Это показывает совершенно другую (плохо выглядящую) анимацию, чем анимация по умолчанию.
Ixx
18

Нажмите на ту же проблему, работая над изменением внешнего вида индикатора выполнения по умолчанию. Вот еще немного информации, которая, надеюсь, поможет людям :)

  • Имя файла xml должно содержать только символы: a-z0-9_. (т.е. без прописных букв!)
  • Чтобы сослаться на ваш "drawable" это R.drawable.filename
  • Чтобы переопределить внешний вид по умолчанию, вы используете myProgressBar.setProgressDrawable(...), однако вам не нужно просто ссылаться на ваш пользовательский макет, так как R.drawable.filenameвам нужно получить его как Drawable:
    Resources res = getResources();
    myProgressBar.setProgressDrawable(res.getDrawable(R.drawable.filename);
  • Вам нужно установить стиль перед настройкой прогресса / вторичного прогресса / максимума (после этого для меня установился «пустой» индикатор выполнения)
pyko
источник
15

Вероятно, есть одна вещь, которая не упоминалась в этом ответе:

Если ваша тема наследуется Theme.AppCompat, ProgressBarпримет цвет, который вы определили как "colorAccent"в вашей теме.

Итак, используя ..

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

... автоматически подкрасит цвет ProgressBar @color/custom_color.

Энрике де Соуза
источник
1
Мне нужно было использовать <item name = "android: colorAccent"> @ color / highlight </ item>
tonisives
15

Вы можете попытаться изменить свои стили, темы или использовать android: indeterminateTint = "@ color / yourColor" в любом месте, где вы хотите, но есть только один способ сделать это, будет работать на любой версии Android SKD:

Если ваш индикатор прогресса не является неопределенным, пожалуйста, используйте:

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

Если ваш индикатор прогресса не определен, пожалуйста, используйте:

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

Печально, что в Android такой беспорядок!

Адриано Моутинью
источник
Спасибо! Это работает для неопределенного ProgressBar, но для определенного оно окрашивает всю шкалу цветом.
CoolMind
14

Как я это сделал в горизонтальном ProgressBar:

    LayerDrawable layerDrawable = (LayerDrawable) progressBar.getProgressDrawable();
    Drawable progressDrawable = layerDrawable.findDrawableByLayerId(android.R.id.progress);
    progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
mieszk3
источник
2
Я сделал то же самое, плюс изменение цвета фона: layerDrawable.findDrawableByLayerId (android.R.id.background) .setColorFilter (trackColor, PorterDuff.Mode.SRC);
Камень Добрев
1
Этот ответ вместе с комментарием @KamenDobrev - единственный, который действительно сделал то, что я хотел. Когда я только устанавливаю цветной фильтр для прорисовки прогресса, цвет фона также менялся.
m_katsifarakis
13

Самое простое решение, если вы хотите изменить цвет в XML-файле макета, используйте приведенный ниже код и используйте свойство indeterminateTint для нужного цвета.

    <ProgressBar
      android:id="@+id/progressBar"
      style="?android:attr/progressBarStyle"
      android:layout_width="wrap_content"
      android:indeterminate="true"
      android:indeterminateTintMode="src_atop"
      android:indeterminateTint="#ddbd4e"
      android:layout_height="wrap_content"
      android:layout_marginBottom="20dp"
      android:layout_alignParentBottom="true"
      android:layout_centerHorizontal="true" />
Навид Ахмад
источник
12

Это решение сработало для меня:

<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
источник
8

Еще одна маленькая вещь, решение для темы работает, если вы наследуете базовую тему, поэтому для app compact ваша тема должна быть:

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

И затем установите это в теме индикатора выполнения

<ProgressBar
    android:id="@+id/progressCircle_progressBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:theme="@style/AppTheme.Custom"
    android:indeterminate="true"/>
Калин
источник
7

Чтобы изменить горизонтальный цвет ProgressBar (в котлине):

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

Чтобы изменить неопределенный цвет ProgressBar:

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

И это, наконец, нормально подкрасить прогресс леденец на палочке

тонированный прогресс на API 19

Джон
источник
6

Пользовательский стиль горизонтального индикатора выполнения:

Изменить цвет фона и прогресс горизонтального индикатора выполнения.

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

Примените его на индикатор выполнения, установив атрибут стиля, для пользовательских стилей материала и проверки пользовательского индикатора выполнения http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples

Арнав Рао
источник
3
для этого требуется минимальный уровень API 21
Shihab Uddin
6

Написал, чтобы добавить информацию об ответе PaulieG , так как ateiob попросил меня кое-что объяснить ...


Я могу сказать, что существует (или, по крайней мере, было, во время написания, когда я смотрел на эту текущую версию исходного кода Android) ошибка / проблема / оптимизация в ProgressBarкоде, которая игнорирует попытку установить прогресс в значение, которое он уже в.

  • т. е. если progress = 45, и вы пытаетесь установить его на 45, код ничего не будет делать и не будет перерисовывать прогресс .

После вызова ProgressBar.setProgressDrawable()ваш индикатор выполнения будет пустым (потому что вы изменили рисованную часть).

Это означает, что вам нужно установить прогресс и перерисовать его. Но если вы просто установите прогресс в сохраненное значение, это ничего не изменит.

Сначала необходимо установить значение 0, затем снова «старое» значение, и полоса будет перерисована.


Итак, подведем итог:

  • сохранить «старое» значение прогресса
  • обновить рисование / цвет (делает панель пустой)
  • сбросить прогресс до 0 (иначе следующая строка ничего не делает)
  • сбросить прогресс до «старого» значения (панель исправлений)
  • Invalidate

Ниже у меня есть метод, который делает это:

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

Что касается решения HappyEngineer, я думаю, что это был похожий обходной путь, чтобы вручную установить смещение «прогресса». В любом случае приведенный выше код должен работать на вас.

Ричард Ле Мезурье
источник
Спасибо .. это действительно работает .. но, поскольку мой drawable был статическим (из ресурсов) .. он не работал. Это сработало только после того, как я добавил "drawable.invalidateSelf ();" перед «setProgress (0)» и «setProgressDrawable (drawable)»
Alécio Carvalho
5

Используйте android.support.v4.graphics.drawable.DrawableCompat :

            Drawable progressDrawable = progressBar.getIndeterminateDrawable();
            if (progressDrawable  != null) {
                Drawable mutateDrawable = progressDrawable.mutate();
                DrawableCompat.setTint(mutateDrawable, primaryColor);
                progressBar.setProgressDrawable(mutateDrawable);
            }
Альесио Карвалью
источник
5

просто используйте:

PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
    mode = PorterDuff.Mode.MULTIPLY;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
    progressBar.setProgressBackgroundTintList(ColorStateList.valueOf(Color.RED));
} else {
    Drawable progressDrawable;
    progressDrawable = (progressBar.isIndeterminate() ? progressBar.getIndeterminateDrawable() : progressBar.getProgressDrawable()).mutate();
    progressDrawable.setColorFilter(context.getResources().getColor(Color.RED), mode);
    progressBar.setProgressDrawable(progressDrawable);
}
Мухаммед Фнейш
источник
4

Для горизонтального стиля ProgressBar я использую:

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

Пример вызова будет:

  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

Если вам не нужен «вторичный прогресс», просто установите value2 в значение1.

Кит
источник
4

Примените этот пользовательский стиль к индикатору выполнения.

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

Используйте этот тип изображения для индикатора выполнения. введите описание изображения здесь

Для лучшего результата вы можете использовать несколько изображений прогресса. И, пожалуйста, не стесняйтесь использовать изображения, потому что сама платформа Android использует изображения для прогрессбара. Код извлекается из SDK :)

Нео
источник
4

Согласно Мухаммаду-адилу, предложенному для SDK ver 21 и выше

android:indeterminateTint="@color/orange"

в XML работает для меня, достаточно просто.

mughil
источник
Если вы хотите изменить для всего приложения, пожалуйста, измените значение <color name = "RedAccent"> # FE6C27 </ color>. в ваших Values ​​/ colors.xml.
Могил
4

Вот код для изменения цвета ProgressBar программно.

ProgressBar progressBar = (ProgressBar) findViewById(R.id.pb_listProgressBar);
int colorCodeDark = Color.parseColor("#F44336");
progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorCodeDark));
Навин Кумар М
источник
4
ProgressBar freeRamPb = findViewById(R.id.free_ram_progress_bar);

freeRamPb.getProgressDrawable().setColorFilter(
Color.BLUE, android.graphics.PorterDuff.Mode.SRC_IN);
исключение нулевого указателя
источник
Потрясающие. Быстрое и эффективное решение. Спасибо!
Тобиас Рейх