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

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

Solutions Collecting From Web of "Как изменить цвет прогресса индикатора выполнения в Android"

Мне жаль, что это не ответ, но что заставляет требование устанавливать его из кода? И .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> 

Для горизонтального ProgressBar вы также можете использовать ColorFilter следующим образом:

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

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

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

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

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

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

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

Пример, где настройка цвета на красный:

 ProgressBar spinner = new android.widget.ProgressBar( context, null, android.R.attr.progressBarStyle); spinner.getIndeterminateDrawable().setColorFilter(0xFFFF0000, android.graphics.PorterDuff.Mode.MULTIPLY); 

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

Это не программно, но я думаю, что это может помочь многим людям! Я пробовал много, и наиболее эффективным способом было добавить эти строки в мой 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+

Это старый вопрос, но использование темы здесь не упоминается. Если ваша тема по умолчанию использует 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 только android:theme . Здесь вы можете найти более широкое использование темы: https://plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH

В соответствии с некоторыми из предложений, вы можете указать форму и clipdrawable с цветом, а затем установить его. У меня это работает программно. Вот как я это делаю.

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

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

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

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

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

 ((ProgressBar)findViewById(R.id.progressBar)) .getIndeterminateDrawable() .setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN); 

В настоящее время в 2016 году я обнаружил, что некоторые устройства pre-Lollipop не colorAccent параметр 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); } 

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

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

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

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

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

… будет автоматически окрашивать цвет ProgressBar в @color/custom_color .

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

  LayerDrawable layerDrawable = (LayerDrawable) progressBar.getProgressDrawable(); Drawable progressDrawable = layerDrawable.findDrawableByLayerId(android.R.id.progress); progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); 
 android:progressTint="#ffffff" 

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

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

Для горизонтального стиля 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 

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

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

К сожалению, когда я предложил изменить решение, это было давно, и я не могу запомнить все детали.


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

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

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

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

Вы должны сначала установить его на 0, затем на «старое» значение, и панель будет перерисовываться.


Итак, чтобы подвести итог:

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

Ниже приведен метод, который у меня есть, – я надеюсь, что это полезно. Я не уверен на 100%, почему я назвал его onResume() – это может быть важно или не связано:

 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, я думаю, что это было похоже на обходное решение, чтобы вручную установить смещение «прогресс» (я точно не помню). В любом случае вышеуказанный код должен работать на вас.

Извините, если я не могу запомнить все детали – вот почему я попытался отредактировать ответ. Надеюсь это поможет…

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

 <ProgressBar android:indeterminateTint="#d60909" ... /> 
 ProgressBar bar; private Handler progressBarHandler = new Handler(); GradientDrawable progressGradientDrawable = new GradientDrawable( GradientDrawable.Orientation.LEFT_RIGHT, new int[]{ 0xff1e90ff,0xff006ab6,0xff367ba8}); ClipDrawable progressClipDrawable = new ClipDrawable( progressGradientDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL); Drawable[] progressDrawables = { new ColorDrawable(0xffffffff), progressClipDrawable, progressClipDrawable}; LayerDrawable progressLayerDrawable = new LayerDrawable(progressDrawables); int status = 0; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // TODO Auto-generated method stub setContentView(R.layout.startup); bar = (ProgressBar) findViewById(R.id.start_page_progressBar); bar.setProgress(0); bar.setMax(100); progressLayerDrawable.setId(0, android.R.id.background); progressLayerDrawable.setId(1, android.R.id.secondaryProgress); progressLayerDrawable.setId(2, android.R.id.progress); bar.setProgressDrawable(progressLayerDrawable); } 

Это помогло мне настроить пользовательский цвет для перехода через код. Надеюсь, поможет

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

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

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

 <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 использует изображения для progressbar. Код извлекается из sdk 🙂

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

 android:indeterminateTint="@color/orange" 

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

Horizontal ProgressBar использует rectangle shape для фона, ClipDrawable построенный из rectangle shape для прогрессивных (первичных и вторичных). Тонирование изменяет цвета на некоторый оттенок. Если вам нужны целые цвета для всех трех отдельно, вы можете использовать ProgressBar.setProgressDrawable() следующим образом:

  LayerDrawable progressBarDrawable = new LayerDrawable( new Drawable[]{ new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{Color.parseColor("#ff0000ff"),Color.parseColor("#ff0000ff")}), new ClipDrawable( new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{Color.parseColor("#ff00ff00"),Color.parseColor("#ff00ff00")}), Gravity.START, ClipDrawable.HORIZONTAL), new ClipDrawable( new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, new int[]{Color.parseColor("#ffff0000"),Color.parseColor("#ffff0000")}), Gravity.START, ClipDrawable.HORIZONTAL) }); progressBarDrawable.setId(0,android.R.id.background); progressBarDrawable.setId(1,android.R.id.secondaryProgress); progressBarDrawable.setId(2,android.R.id.progress); ((ProgressBar)findViewById(R.id.progressBar)).setProgressDrawable(progressBarDrawable); 

Обратите внимание, что порядок вытягиваемых слоев важен при инициализации LayerDrawable . Первый вариант должен быть для фона. В соответствии с моим экспериментом переключения идентификаторов не работают. Если вы установите padding в progressbar то этот подход не будет работать. Если вам требуется заполнить, вы можете использовать контейнер для LinearLayout прогресса, например LinearLayout .

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

Попробуйте вот так:

Объявить ниже атрибут attrs.xml

  <attr name="circularProgressTheme" format="reference"></attr> 

Вставьте под кодом в styles.xml

  <style name="ProgressThemeWhite" parent="ThemeOverlay.AppCompat.Light"> <item name="colorAccent">#FF0000</item> </style> <style name="circularProgressThemeWhite"> <item name="android:theme">@style/ProgressThemeWhite</item> </style> <style name="AppTheme" parent="Theme.AppCompat.NoActionBar"> <item name="circularProgressTheme">@style/circularProgressThemeWhite</item> </style> 

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

  <ProgressBar style="?attr/circularProgressTheme" android:id="@+id/commonProgress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="visible"/> 

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

 ProgressBar progressBar = (ProgressBar) findViewById(R.id.pb_listProgressBar); int colorCodeDark = Color.parseColor("#F44336"); progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorCodeDark)); 

Это сработало для меня и является простым решением.

 progressDialog.setMessage( Html.fromHtml("<font color='white'>" + Message + "</font>"));