Como alterar a cor do progresso da barra de progresso no Android

473

Estou usando uma barra de progresso horizontal no meu aplicativo Android e quero alterar sua cor de progresso (que é amarelo por padrão). Como posso fazer isso usando code(não XML)?

WhiteTigerK
fonte
Você já tentou MyProgressBar.setProgressDrawable (Drawable d) especificando um bitmap com a cor desejada? developer.android.com/reference/android/widget/… developer.android.com/reference/android/graphics/drawable/…
fupsduck
2
Sim, eu tentei, mas não funciona. Ele define a cor de plano de fundo de toda a exibição da barra de progresso, em vez de definir a cor de plano de fundo apenas da própria barra. Obrigado.
WhiteTigerK
21
android:indeterminateTint="@android:color/white"funciona apenas na API> = 21
Madeyedexter 19/08/19

Respostas:

291

Lamento que não seja a resposta, mas o que está impulsionando o requisito de defini-lo a partir do código? E .setProgressDrawabledeve funcionar se estiver definido corretamente

<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>
Alex Volovoy
fonte
4
O motivo é que estou criando a barra de progresso dinamicamente e definindo sua cor mediante solicitação do usuário. Como geralmente uso código para criar minha tela e componentes da GUI, não estou familiarizado com o XML anexado e não sei o que é uma lista de camadas (embora eu esteja supondo que você esteja criando a barra de progresso com base em várias camadas ..) Caso eu queira usar o XML que você anexou - onde devo colocá-lo na pasta do projeto e há mais alguma coisa que preciso fazer para criar uma barra de progresso com base nas configurações de XML? Obrigado.
WhiteTigerK
1
Salve esse xml como um arquivo e coloque-o na pasta drawable (digamos my_progress.xml) e defina-o como My drawable em MyProgressBar.setProgressDrawable () Para alterar as cores, você precisará alterar esses valores em @ color / progress_start @ color / progress_end É basicamente um gradiente e você pode colocar hexadecimal lá.
Alex Volovoy
3
Nota - arquivo é a cópia da que está no SDK. Soltei os direitos autorais aqui. Se você olhar na pasta res / drawable, verá exatamente o que eu publiquei - as cores são definidas para o gradiente amarelo, em vez das cores personalizadas.
precisa saber é o seguinte
7
Não mostra nenhuma mudança de cor para mim. por favor, diga a cor que deu certo.
Praveen
Oi Alex, suas respostas são muito legais. mas, tentei alterar a cor da roda de progresso personalizada em tempo de execução. mas eu não pude. por favor me ajude a resolver o meu problema .. depois que o progresso chegar a 100%, então mude a cor e inicie o progresso .. eu
baixo o
485

Para uma ProgressBar horizontal, você também pode usar um ColorFilterassim:

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

ProgressBar vermelho usando filtro de cores

Nota: isso modifica a aparência de todas as barras de progresso no seu aplicativo. Para modificar apenas uma barra de progresso específica, faça o seguinte:

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

Se progressBar for indeterminado, use em getIndeterminateDrawable()vez de getProgressDrawable().

Desde o Lollipop (API 21), você pode definir um tom de progresso:

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

ProgressBar vermelho usando tonalidade de progresso

Torben Kohlmeier
fonte
7
Eu queria usar essa resposta, pois me pareceu a mais simples, mas minha barra de progresso está completamente vermelha, independentemente do valor do progresso. Você tem certeza do modo de usar?
LG
33
@ resus Eu tenho o mesmo problema, a barra estava totalmente vermelha e nenhum progresso foi visível. Mas eu resolvi mudar Mode.SRC_IN para Mode.MULTIPLY.
Derzu
40
Não se esqueça de fazer o mesmo, getIndeterminateDrawablese você estiver usando progresso indeterminado.
Thommy
6
Lembre-se de que 'Mode' neste contexto refere-se a android.graphics.PorterDuff.Mode #
1owk3y
9
como não mudar a cor de fundo? Eu só quero mudar a cor do progresso.
kangear
364

Isso não é programático, mas acho que poderia ajudar muitas pessoas de qualquer maneira.
Eu tentei muito e a maneira mais eficiente era adicionar essas linhas ao meu ProgressBar no arquivo .xml:

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

Então, no final, esse código fez isso por mim:

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

Esta solução funciona para API 21+

FFirmenich
fonte
45
Requer nível mínimo de API 21
Apfelsaft
Também existem métodos de configuração para essas propriedades que podem ser chamados se a cor dinâmica precisar ser definida.
CCR
Preciso criar um arquivo de recurso personalizado para as API 21+ e API <= 20? Ou esses atributos são ignorados na API <= 20?
usar o seguinte comando
1
@shriduttkothari como pode ser o melhor? ... it 21+
user25
2
A melhor resposta que o Android se afasta 4.x mínimo
Tom
229

Para minha barra de progresso indeterminada (botão giratório), acabei de definir um filtro de cores no drawable. Funciona muito bem e apenas uma linha.

Exemplo onde definir cor para vermelho:

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

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

insira a descrição da imagem aqui

jhavatar
fonte
16
Eu gosto mais da sua resposta. Para que o meu funcionasse, tive que fazer isso: myProgressBarSpinner.getIndeterminateDrawable (). SetColorFilter (novo LightingColorFilter (0xFF000000, foregroundColorDesired));
Art Geigel
4
Observe também que isso fará com que todas as barras de progresso sejam modificadas em seu aplicativo. Para fazer isso apenas em um particular, chame mutate () no drawable, defina o filtro de cores e chame setIntederminateDrawable no seu progressBar.
dimsuz
3
NB: Aqueles que usam isso e se perguntam por que sua cor não se parece exatamente com a string hexadecimal que inserem, possui um filtro de várias cores. Mude android.graphics.PorterDuff.Mode.MULTIPLYpara PorterDuff.Mode.SRC_INe você obterá a cor hexadecimal exata.
micnguyen
Eu acho que ele só precisa esta resposta ..... android: indeterminateTint = "@ android: cor / preto"
Muhammad Adil
4
eu usei como: progressBar = (ProgressBar) findViewById (R.id.progressBar); progressBar.getIndeterminateDrawable (). setColorFilter (ContextCompat.getColor (este, android.R.color.white), android.graphics.PorterDuff.Mode.MULTIPLY);
ashishdhiman2007
188

Esta é uma pergunta antiga, mas o uso do tema não é mencionado aqui. Se o seu tema padrão estiver em uso AppCompat, será a sua ProgressBarcor que colorAccentvocê definiu.

Mudar colorAccenttambém mudará a ProgressBarcor da sua, mas também haverá reflexos em vários locais. Portanto, se você quiser uma cor diferente apenas para uma determinada, PregressBarpoderá fazer isso aplicando o tema a isso ProgressBar:

  • Estenda seu tema padrão e substitua colorAccent

    <style name="AppTheme.WhiteAccent">
        <item name="colorAccent">@color/white</item> <!-- Whatever color you want-->
    </style>
  • E ProgressBaradicione o android:themeatributo:

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

Portanto, será algo parecido com isto:

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

Então você está apenas mudando um colorAccentpara o seu particular ProgressBar.

Nota : O uso stylenão funcionará. Você precisa usar android:themeapenas. Você pode encontrar mais uso do tema aqui: https://plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH

kirtan403
fonte
18
finalmente! graças, parece que não muitos desenvolvedores usam AppCompat, muitos usuários só voto-ups respostas com solução para API 21+, não é bom em tudo, eles devem suportar mais dispositivos / OS possível
USER25
1
Impressionante! Funcionou para mim, mas eu tinha que ter certeza de que havia um pai = "@ style / Theme.AppCompat" em algum lugar da hierarquia de estilos. Eu tinha outro pai e ele não funcionou no começo.
Nublodeveloper 24/01
@ Nublodeveloper Sim, eu mencionei isso na primeira linha, se você notou.
precisa saber é o seguinte
1
@ kirtan403 Ah, sim, entendi agora, você mencionou, mas não entendi dessa maneira quando li pela primeira vez. Eu li muito rápido e estava procurando por código. Obrigado mesmo assim, sua resposta é a melhor para mim!
Nublodeveloper 24/01
+1 Gostei da sua solução. Mas como definir a cor do tema em java ??? Por exemplo, se eu quero que sejam vermelhos <nome do color = "red"> # ff5900 </ color>
Maseed
54

All API

se usar toda API, basta criar o tema com estilo

style.xml

<resources>

    //...

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

</resources>

e uso em andamento

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

API nível 21 e superior

se usado no nível 21 da API e superior, basta usar este código:

<ProgressBar
   //...
   android:indeterminate="true"
   android:indeterminateTintMode="src_atop"
   android:indeterminateTint="@color/secondary"/>
Rasoul Miri
fonte
1
Bom, eu acho que método style.xml é melhor (não é necessário acima de 20 API).
iamkdblue
1
Melhor solução, se você deseja uma solução para todas as APIs Obrigado :)
Naveen
34

de acordo com algumas das sugestões, você pode especificar uma forma e extraível com uma cor e defini-la. Eu tenho isso trabalhando programaticamente. É assim que eu faço ..

Primeiro, certifique-se de importar a biblioteca de desenho.

import android.graphics.drawable.*;

Em seguida, use o código semelhante ao abaixo;

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
fonte
1
Eu tentei o código acima, infelizmente, apenas resulta em uma barra de progresso "vazia". Estou esquecendo de algo?
OceanBlue 17/05
Você precisa chamar setLevel no ClipDrawable. Leva um valor de 0 a 10000. Portanto, progress.setLevel (2500) estaria 25% cheio.
HappyEngineer 19/09/11
1
Eu enviei uma edição para a resposta que explica uma das razões para um "vazio" barra de progresso - e 2 maneiras de corrigi-lo (incl @ de HappyEngineer correção)
Richard Le Mesurier
@RichardLeMesurier você pode postar a explicação + 2 maneiras na seção de comentários? progress.setLevel(2500)não funciona para mim e, aparentemente, sua edição não foi aceita por algum motivo. Obrigado. +1.
ateiob
@ateiob eu ter escrito uma nova resposta para explicar ...
Richard Le Mesurier
32

Isso funcionou para mim:

<ProgressBar
 android:indeterminateTint="#d60909"
 ... />
MOH3N
fonte
12
Usado apenas no nível 21 da API e superior
Numair
28

se indeterminado:

((ProgressBar)findViewById(R.id.progressBar))
    .getIndeterminateDrawable()
    .setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
a faca
fonte
Eu usei isso, mas não animado, apenas cor foi aplicada ... Eu estou usando progressbar circular
Manikandan
24

Isso funciona para mim. Também funciona para a versão inferior. Adicione isso ao seu syles.xml

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

E use-o assim em xml

<ProgressBar
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:theme="@style/ProgressBarTheme"
   />
Devinder Jhinjer
fonte
Eu implementei isso no aplicativo de exemplo CryptoTweets . Descobri que o tema pai não é necessário para que esta solução funcione conforme o esperado. parent="ThemeOverlay.AppCompat.Light"
Adam Hurwitz
23

Atualmente, em 2016, descobri que alguns dispositivos pré-pirulito não respeitam a colorAccentconfiguração, então minha solução final para todas as APIs agora é a seguinte:

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

Para pontos de bônus, ele não usa nenhum código obsoleto. Tente!

Henrique de Sousa
fonte
Não se esqueça de ligar wrapDrawable.mutate()comDrawableCompat.setTint(wrapDrawable.mutate(), ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
Tarsem Singh
Não funciona no Android KitKat 4.4.2.
Pradip tilala
Tentei (novamente) em um emulador novo 4.4.2 e funciona sem problemas, verifique suas .xmlconfigurações e também se algo mais está substituindo a ProgressBarcor.
Henrique de Sousa
20

Isto é o que eu fiz. Trabalhou.

Barra de progresso:

<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:
use o gradiente para alterar a cor conforme desejar. E android: toDegrees = "X" aumenta o valor de X e a barra de progresso gira rapidamente. Diminua e gire lentamente. Personalize de acordo com suas necessidades.

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

amostra: insira a descrição da imagem aqui

Debasish Ghosh
fonte
Isso mostra uma animação totalmente diferente (de má aparência) da animação padrão.
Ixx
18

Bata no mesmo problema ao trabalhar na modificação da aparência da barra de progresso padrão. Aqui estão mais algumas informações que esperamos ajudar as pessoas :)

  • O nome do arquivo xml deve conter apenas caracteres: a-z0-9_.(ou seja, sem maiúsculas!)
  • Para referenciar seu "drawable" é R.drawable.filename
  • Para substituir a aparência padrão, você usa myProgressBar.setProgressDrawable(...), no entanto, você não pode apenas se referir ao seu layout personalizado como R.drawable.filename, é necessário recuperá-lo como Drawable:
    Resources res = getResources();
    myProgressBar.setProgressDrawable(res.getDrawable(R.drawable.filename);
  • Você precisa definir o estilo antes de definir o progresso / progresso secundário / máximo (defini-lo posteriormente para mim resultou em uma barra de progresso 'vazia')
pyko
fonte
15

Provavelmente há uma coisa que não foi mencionada nesta resposta:

Se o seu tema for herdado Theme.AppCompat, ProgressBarassumirá a cor que você definiu como "colorAccent"no seu tema.

Então, usando ..

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

..pintará a cor da ProgressBar automaticamente para a @color/custom_color.

Henrique de Sousa
fonte
1
Eu precisava usar <item name = "android: colorAccent"> @ cor / highlight </ item>
tonisives
15
android:progressTint="#ffffff" 
Paulo
fonte
15

Você pode tentar alterar seus estilos, temas ou usar o android: indeterminateTint = "@ color / yourColor" onde quiser, mas há apenas uma maneira de fazer isso que funcionará em qualquer versão do Android SKD:

Se a barra de progresso não for indeterminada, use:

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

Se a barra de progresso for indeterminada, use:

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

É triste que o Android seja uma bagunça!

Adriano Moutinho
fonte
Obrigado! Funciona por indeterminado ProgressBar, mas por determinado pinta escala inteira com cores.
CoolMind 28/09/19
14

Como eu fiz isso na ProgressBar horizontal:

    LayerDrawable layerDrawable = (LayerDrawable) progressBar.getProgressDrawable();
    Drawable progressDrawable = layerDrawable.findDrawableByLayerId(android.R.id.progress);
    progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
mieszk3
fonte
2
Fiz a mesma coisa, além da alteração da cor de plano de fundo: layerDrawable.findDrawableByLayerId (android.R.id.background) .setColorFilter (trackColor, PorterDuff.Mode.SRC);
Kamen Dobrev
1
Esta resposta, juntamente com o comentário de @KamenDobrev, é a única que realmente fez o que eu queria. Quando eu apenas defini um filtro de cores para o progresso desenhável, a cor do plano de fundo também foi alterada.
M_katsifarakis
13

Solução mais simples, se você quiser alterar a cor no arquivo xml de layout, use o código abaixo e use a propriedade indeterminateTint para a cor desejada.

    <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" />
Namaded Ahmad
fonte
12

Esta solução funcionou para mim:

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

Mais uma coisa, a solução do tema funciona se você herdar um tema base; portanto, para o compact app, seu tema deve ser:

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

E então defina isso no tema da barra de progresso

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

Para alterar a cor horizontal da ProgressBar (em kotlin):

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

Para alterar a cor ProgressBar indeterminada:

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

E, finalmente, normalmente tinge o progresso pré-pirulito

progresso matizado na API 19

John
fonte
6

Estilo de material personalizado da barra de progresso horizontal:

Para alterar a cor do plano de fundo e o progresso da barra de progresso horizontal.

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

Aplique-o à barra de progresso definindo o atributo style, para estilos de materiais personalizados e verificação de barra de progresso personalizada http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples

Arnav Rao
fonte
3
isso requer nível mínimo de API 21
Shihab Uddin
6

Postado para adicionar informações sobre a resposta de PaulieG , já que ateiob me pediu para explicar uma coisa ...


Posso dizer que existe (ou pelo menos havia, no momento em que escrevi, quando olhei para a versão atual do código-fonte do Android) um bug / problema / otimização no ProgressBarcódigo que ignora uma tentativa de definir o progresso como um valor já está em.

  • ou seja, se progress = 45, e você tentar defini-lo como 45, o código não fará nada e não redesenhará o progresso .

Após a chamada ProgressBar.setProgressDrawable(), sua barra de progresso ficará em branco (porque você alterou a parte extraível).

Isso significa que você precisa definir o progresso e redesenhá-lo. Mas se você apenas definir o progresso para um valor preservado, ele não fará nada.

Você deve defini-lo como 0 primeiro, depois com o valor "antigo" novamente e a barra será redesenhada.


Então, para resumir:

  • preservar o valor do progresso "antigo"
  • atualizar o drawable / color (deixa a barra em branco)
  • redefina o progresso para 0 (caso contrário, a próxima linha não fará nada)
  • redefina o progresso para o valor "antigo" (barra de correções)
  • invalidar

Abaixo está um método que tenho que faz isso:

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

Quanto à solução do HappyEngineer, acho que foi uma solução alternativa, definir manualmente o deslocamento do "progresso". Em qualquer um dos casos, o código acima deve funcionar para você.

Richard Le Mesurier
fonte
Obrigado .. isso funciona de fato .. mas como meu drawable era estático (de recursos) .. não funcionou. Ele só funcionou depois que adicionei "drawable.invalidateSelf ();" antes de 'setProgress (0)' e 'setProgressDrawable (drawable)'
Alécio Carvalho
5

Use o android.support.v4.graphics.drawable.DrawableCompat :

            Drawable progressDrawable = progressBar.getIndeterminateDrawable();
            if (progressDrawable  != null) {
                Drawable mutateDrawable = progressDrawable.mutate();
                DrawableCompat.setTint(mutateDrawable, primaryColor);
                progressBar.setProgressDrawable(mutateDrawable);
            }
Alécio Carvalho
fonte
5

basta usar:

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);
}
Mohammad Fneish
fonte
4

Para um estilo horizontal ProgressBar, eu uso:

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

Uma chamada de exemplo seria:

  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

Se você não precisar do 'progresso secundário', basta definir valor2 como valor1.

Keith
fonte
4

Aplique esse estilo personalizado à barra de progresso.

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

Use este tipo de imagem para a barra de progresso. insira a descrição da imagem aqui

Para um melhor resultado, você pode usar várias imagens de progresso. E não hesite em usar imagens, porque a própria plataforma Android usa imagens para a barra de progresso. O código é extraído do sdk :)

Neo
fonte
4

Conforme muhammad-adil sugerido para SDK ver 21 e acima

android:indeterminateTint="@color/orange"

no XML Works para mim, é fácil o suficiente.

mughil
fonte
Se você deseja alterar para todo o aplicativo, altere o valor de <color name = "RedAccent"> # FE6C27 </color>. em seus valores / colors.xml.
Mckil 30/05
4

Aqui está o código para alterar a cor do ProgressBar programaticamente.

ProgressBar progressBar = (ProgressBar) findViewById(R.id.pb_listProgressBar);
int colorCodeDark = Color.parseColor("#F44336");
progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorCodeDark));
Naveen Kumar M
fonte
4
ProgressBar freeRamPb = findViewById(R.id.free_ram_progress_bar);

freeRamPb.getProgressDrawable().setColorFilter(
Color.BLUE, android.graphics.PorterDuff.Mode.SRC_IN);
Null Pointer Exception
fonte
Impressionante. Solução rápida e eficaz. Obrigado!
Tobias Reich