Como alterar a cor do indicador de progresso do ProgressBar no Android

178

Eu configurei Horizontal ProgressBar.

Gostaria de mudar a cor do progresso para amarelo.

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

O problema é que a cor do progresso é diferente em diferentes dispositivos. Então, quero corrigir a cor do progresso.

Nishant Shah
fonte
as respostas acima alteram toda a cor do plano de fundo e é ambíguo que altere a altura da barra de progresso para muito max.which que não pode alterar em xml. A melhor maneira de alterar apenas o status da barra de progresso é o quanto concluído: 20% na cor vermelha, 50% na cor amarela 70% e acima da cor verde. você pode fazer isso programaticamente em java. compartilhe sua resposta se você tiver outra solução.
Mubashar

Respostas:

365

Copiei isso de um dos meus aplicativos, então há alguns atributos extras, mas você deve ter uma idéia. Isto é do layout que possui a barra de progresso:

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

Em seguida, crie um novo drawable com algo semelhante ao seguinte (neste caso 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>

Você pode alterar as cores conforme necessário, isso fornecerá uma barra de progresso verde.

Ryan
fonte
E também eu remover esse android: indeterminado = "false"
Nishant Shah
2
Por favor me ajude. Tento criar greenprogress.xml copiando seu código, mas a Android Studio 0.4.6 marca <layer-list> como e o erro "A lista de elementos deve ser declarada" o que devo fazer?
UmAnusorn 25/02
1
É possível mudar a cor dinamicamente?
async 29/05
a cor pode ser alterada dependendo do valor atual do progresso definido na barra real?
Jonathan
@ Ryan Seria útil para explicar o que android:id="@android:id/progress", android:id="@android:id/background"e android:id="@android:id/secondaryProgress"repousar.
RustamG
103

Uma solução mais simples:

progess_drawable_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>
Nitin Saxena
fonte
1
aqui @ cor / desativado é uma cor personalizada
Nitin Saxena
2
Ou <android sólido: color = "@ android: color / preto" />, ou mesmo <android sólido: color = "# ff33b5e5" />
superarts.org
2
Este é o suficiente android: indeterminateTint = "@ cor / branco" para a API alavanca 21 e acima
Ghanshyam Nayma
53

Basta criar um estilo no values/styles.xml.

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

Em seguida, defina esse estilo como seu ProgressBartema.

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

e não importa que sua barra de progresso seja horizontal ou circular. Isso é tudo.

Ali Zeynali
fonte
1
Uau, a solução mais simples, funciona para mim. Eu me perguntava por que essa resposta tem tantos votos.
Pavel Shorokhov
38

Se você deseja alterar apenas a cor da barra de progresso, basta usar um filtro de cores no método onCreate () da sua atividade:

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

Idéia daqui .

Você só precisa fazer isso nas versões pré-pirulito. No Lollipop, você pode usar o atributo de estilo colorAccent.

amfcosta
fonte
Por SeekBarque é o mesmo, basta adicionar a API 16: seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);. Isso mudará a cor do polegar redondo.
Sufian
1
Chamar setColorFilter()um drawable diretamente aplicará a cor em qualquer lugar. Como isso é o que eu não precisava, eu apenas liguei mutate()no Drawable(ou seja,seekBar.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Sufian,
3
Eu vi esta solução em outros lugares, mas tudo que ele faz (testes em um dispositivo Gingerbread) é transformar toda a barra de progresso que uma cor, o que torna impossível ver o progresso real
Neil C. Obremski
@ NeilC.Obremski sim, você está certo. Pode ser específico da ROM ou talvez versão específica. Eu tive que removê-lo completamente. Esperamos ter isso em breve para versões mais antigas do Android (via support lib).
Sufian
25

para o nível 21 ou superior da API, basta usar

android:progressBackgroundTint="@color/yourBackgroundColor"
android:progressTint="@color/yourColor"
Mohammad Mousavi
fonte
6

Existem 3 maneiras de resolver esta questão:

  1. Como ajustar a cor da barra de progresso declarativamente
  2. Como ajustar a cor da barra de progresso programaticamente, mas escolha a cor de várias cores predeterminadas declaradas antes do tempo de compilação
  3. Como ajustar a cor da barra de progresso programaticamente e também criar a cor programaticamente.

Em particular, há muita confusão em torno de # 2 e # 3, como visto nos comentários à resposta de amfcosta. Essa resposta produzirá resultados imprevisíveis de cores sempre que você desejar definir a barra de progresso para qualquer coisa, exceto cores primárias, pois apenas modifica a cor do plano de fundo, e a área "clipe" da barra de progresso real ainda será uma sobreposição amarela com opacidade reduzida. Por exemplo, usar esse método para definir o plano de fundo como roxo escuro resultará em uma barra de progresso com uma cor rosada louca resultante da mistura de roxo escuro e amarelo via alfa reduzido.

De qualquer forma, o nº 1 é respondido perfeitamente por Ryan e Štarke responde a maior parte do nº 3, mas para quem procura uma solução completa para os nºs 2 e 3:


Como ajustar a cor da barra de progresso programaticamente, mas escolha a cor de uma cor predeterminada declarada em XML

res / drawable / my_progressbar.xml :

Crie esse arquivo, mas altere as cores em my_progress e my_secondsProgress:

(NOTA: Esta é apenas uma cópia do arquivo XML real que define o SDK Android ProgressBar padrão do Android, mas alterei os IDs e as cores. O original é chamado 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>

No seu 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)

Como ajustar a cor da barra de progresso por meio de programação e também criar a cor por meio de programação

EDIT: Encontrei tempo para resolver isso corretamente. Minha resposta anterior deixou isso um pouco ambíguo.

Um ProgressBar é composto como 3 Drawables em um LayerDrawable.

  1. A camada 1 é o plano de fundo
  2. Camada 2 é a cor do progresso secundário
  3. A camada 3 é a principal cor da barra de progresso

No exemplo abaixo, alterarei a cor da barra de progresso principal para ciano.

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

Esse exemplo definiu uma cor sólida. Você pode configurá-lo para uma cor gradiente substituindo

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

com

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

Felicidades.

-Lança

lance.dolan
fonte
o que é viewUtils em viewUtils.convertDpToPixel (5);
Nikos Hidalgo
1
Olá @NikosHidalgo - Você pode ver um método quase idêntico aqui: stackoverflow.com/questions/12849366/… . A única diferença é que eu construir minha ViewUtilscom uma referência a Context, de modo que eu não preciso passar um Contextao chamarconvertDpToPixel()
lance.dolan
Obrigado por sua pronta resposta, especialmente em uma resposta publicada há muito tempo!
Nikos Hidalgo
Haha, eu realmente tive que esticar meu cérebro para lembrar: p
lance.dolan
4

Se você estiver no nível 21 ou superior da API, poderá usar estes atributos XML:

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

A solução mais simples que descobri é algo como isto:

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

Coloque o styles.xmlarquivo acima na res > valuespasta.

NOTA: Se você usar qualquer outra cor de destaque, as soluções anteriores devem ser boas.

API 21 ou MAIS ALTA

Sazid
fonte
Esta é a melhor solução. 100% relacionado à pergunta feita. muito simples
Pir Fahim Shah
3
final LayerDrawable layers = (LayerDrawable) progressBar.getProgressDrawable();
layers.getDrawable(2).setColorFilter(color,PorterDuff.Mode.SRC_IN);
user3135773
fonte
1
Tente adicionar uma pequena explicação à sua resposta. As respostas apenas de código são desencorajadas.
Alexei
Gostaria de obter uma explicação por trás do índice 2 no getDrawable, mas pelo menos essa foi a única solução que funcionou para mim, então obrigado!
Nikos Hidalgo
2

Para quem procura como fazê-lo programaticamente:

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

Definir ids para drawables é crucial e cuida da preservação dos limites e da barra de estado real do progresso

Štarke
fonte
1

Vocês estão realmente me dando dor de cabeça. O que você pode fazer é tornar sua lista de camadas desenhável via xml primeiro (significando um plano de fundo como a primeira camada, um desenhável que representa o progresso secundário como a segunda camada e outro desenhável que representa o progresso primário como a última camada) e depois altere a cor no código, fazendo o seguinte:

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

Esse método oferece a melhor flexibilidade de declarar a medição do seu drawable original no xml, SEM MODIFICAÇÃO NA ESTRUTURA APÓS A ESTRUTURA, especialmente se você precisar ter a pasta da tela de arquivo xml específica e modificar apenas ONLY THE COLOR via código. Não é necessário re-instanciar um novo ShapeDrawable do zero.

Pier Betos
fonte
1

A cor ProgressBar pode ser alterada da seguinte maneira:

/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);
}
Milan Hlinák
fonte
1

Crie um recurso drawable de que plano de fundo você precisa, no meu caso, chamei-o de 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>

Em seguida, use esse plano de fundo personalizado como

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

Funciona bem para mim

Md Juyel Rana
fonte
0

Em 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
    }
Soumen Das
fonte
0

Com a Biblioteca de componentes de material, você pode usar ProgressIndicatoro app:indicatorColoratributo com para alterar a cor:

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

insira a descrição da imagem aqui

Nota : requer pelo menos a versão 1.3.0-alpha01.

Com o ProgressBarvocê pode substituir a cor usando:

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

com:

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

insira a descrição da imagem aqui

Gabriele Mariotti
fonte
0

Se você deseja definir a cor do progresso primário e secundário para a barra de progresso horizontal programaticamente no android, use o snippet abaixo

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));
Rahul Kamble
fonte