Customizando ProgressBar dinamicamente

Benhur Souza
3 min readNov 1, 2018

--

É natural no mundo dos aplicativos ter customizações personalizadas para cada tipo ou segmento de usuários e muitas das vezes essas personalizações sao envidas para nosso CORE (ou backend).

Por exemplo, estava trabalhando em um aplicativo, onde em determinado período do ano, existiam data, semanas ou meses importantes. Logo, seria legal dar um destaque em certas partes do app. Então nosso time de design decidiu mudar a cor de determinada parte do app para deixar mais chamativo.

Esse tipo de abordagem é muito comum, com certeza você já viu esse tipo de ação acontecer. Os mais famosos que podems lembrar é o Outubro rosa ou Novembro Azul. Muitas empresas mostram solidariedade sobre essas ações e externalizam seu apoio a causa mudando as cores do site ou app.

Então, chega de blablabla e vamos ao que interessa.

Criando um drawable para customizar nosso progressbar

<?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="#53207B" />
</shape>
</item>
<item
android:id="@android:id/progress">
<clip>
<shape>
<solid
android:color="#F34349" />
</shape>
</clip>
</item>
</layer-list>

No código acima criamos um xml(custom_progressbar.xml), com as duas cores o progress:

Background: A parte que ainda não esta preenchida do progressbar;

Progress: A parte que já esta em progresso.

Agora basta adicionar esse drawable no nosso progressbar dentro do nosso layout xml. Simples asssim:

<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="32dp"
android:layout_below="@+id/btn_change_progress"
style="?android:attr/progressBarStyleHorizontal"
android:background="@drawable/custom_progressbar"
android:layout_centerInParent="true"/>

Você deve esta agora pesando:

"Tá bom, tudo bem… mas com isso ai eu não consigo fazer minha customização dinamicamente."

Calma, vamos mostrar agora que é tão simples como a primeira parte, pois elas se complementam. Pois, para essa segunda parte funcionar, teremos que adicionar a primeira também.

Pode-se notar que ao criar o custom_progressbar.xml, cada item tinha um id. Então usaremos esses ids para poder identificar cada sessão do nosso progressBar, usando o findDrawableByLayerId.

progress.progressDrawable = this.resources.getDrawable(R.drawable.custom_progressbar);val layerDrawable = progress.progressDrawable as LayerDrawable

val bgGradientDrawable = layerDrawable
.findDrawableByLayerId(android.R.id.background) as GradientDrawable
bgGradientDrawable.setColor(offColor)
val progressGradientDrawable = layerDrawable
.findDrawableByLayerId(android.R.id.progress) as ClipDrawable
progressGradientDrawable.setColorFilter(onColor, PorterDuff.Mode.SRC_IN)

No código acima, primeiramente temos que pegar o background do progress que desejamos alterar. Fazemos isso usando progress.progressDrawable ele é do tipo LayerDrawable e tem um método chamada findDrawableByLayerId que usaremos para encontrar cada sessão do nosso progress.

Ao usar o findDrawableByLayerId ele retorna um objeto que devemos saber o tipo. De acordo com o que colocamos no nosso custom_progressbar.xml, sabemos que o background é um GradientDrawable e o progress é um ClipDrawable.

Após encontrar cada um desses elementos, basta trocar suas cores usando os métodos específicos para cada tipo (setColor e setColorFilter).

Resultado final

Escrevi um exemplo usando o que descrevi acima, para poder ilustrar melhor e ajudar ao amiguinhos que só querem usar a técnica do copia e cola.

--

--