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.


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.


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>

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.


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.


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"

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


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"

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


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

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


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.


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

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


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
    }

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


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));
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.