Introduction
This code demonstrates two methods for programmatically changing the color of a progress bar in an Android application written in Kotlin. The code also includes a button click listener that initiates a simulated task that updates the progress bar value and text view.
Explanation
MainActivity.kt
- The
progressStatus
variable is an integer that keeps track of the progress bar's fill level. - The
handler
variable is a Handler instance used to update the UI elements from a background thread.
- The
onCreate() method:
This method inflates the activity_main.xml layout and retrieves references to the widgets:
- Button (
button
) - TextView (
textView
) - Three ProgressBars (
progressBar
,progressBar2
,progressBar3
)
- Button (
Setting progress bar color (tint) programmatically:
- The code sets the
progressTintList
andprogressBackgroundTintList
properties ofprogressBar2
to a ColorStateList with a blue color. This approach works for all API levels.
- The code sets the
Another way to change progress bar color:
- The code checks the Android version using
Build.VERSION.SDK_INT
. - If the API level is 29 (Android 10) or higher, it uses a
BlendModeColorFilter
with the source-in blend mode to set the progress bar's color filter to red. - For lower API levels, it uses a
ColorFilter
with the source-in PorterDuff mode to achieve the same effect.
- The code checks the Android version using
Button click listener:
- When the button is clicked, a new thread is started.
- Inside the thread, a loop iterates until
progressStatus
reaches 100. - Within the loop:
- The
progressStatus
is incremented by 1. - The thread sleeps for 100 milliseconds to simulate some work being done.
- The
- The
handler.post()
method is used to update the UI elements from the background thread:- The progress of all three progress bars (
progressBar
,progressBar2
,progressBar3
) is set to the currentprogressStatus
. - The text view's text is updated to display the current
progressStatus
.
- The progress of all three progress bars (
activity_main.xml
- This file defines the layout of the activity, including:
- A TextView to display the progress status
- Three ProgressBars
- A Button to start the simulated task
- This file defines the layout of the activity, including:
Summary
This code provides a comprehensive example of how to programmatically change the color of a progress bar in Android using Kotlin. It covers two different approaches and also demonstrates how to update the progress bar value and text view from a background thread.
package com.cfsuman.kotlintutorials
import android.app.Activity
import android.content.res.ColorStateList
import android.graphics.BlendMode
import android.graphics.BlendModeColorFilter
import android.graphics.Color
import android.graphics.PorterDuff
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.widget.Button
import android.widget.ProgressBar
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
class MainActivity : Activity() {
var progressStatus = 0
var handler = Handler(Looper.getMainLooper())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Get the widgets reference from XML layout
val button = findViewById<Button>(R.id.button)
val textView = findViewById<TextView>(R.id.textView)
val progressBar = findViewById<ProgressBar>(R.id.progressBar)
val progressBar2 = findViewById<ProgressBar>(R.id.progressBar2)
val progressBar3 = findViewById<ProgressBar>(R.id.progressBar3)
// set progressbar color (tint) programmatically
progressBar2.progressTintList = ColorStateList.valueOf(Color.BLUE)
progressBar2.progressBackgroundTintList = ColorStateList
.valueOf(Color.BLUE)
// another way to change progress bar color
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
progressBar3.progressDrawable.colorFilter =
BlendModeColorFilter(Color.RED, BlendMode.SRC_IN)
}else {
progressBar3.progressDrawable
.setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN)
}
// set button click listener
button.setOnClickListener {
Thread {
while (progressStatus < 100) {
// update progress status
progressStatus += 1
// sleep the thread for 100 milliseconds
Thread.sleep(100)
// update the progress bar
handler.post {
progressBar.progress = progressStatus
progressBar2.progress = progressStatus
progressBar3.progress = progressStatus
textView.text = "$progressStatus"
}
}
}.start()
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp"
android:background="#DCDCDC">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:padding="12dp"
android:fontFamily="sans-serif"
android:textSize="20sp"
android:textStyle="bold"
tools:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<ProgressBar
android:id="@+id/progressBar2"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressBar" />
<ProgressBar
android:id="@+id/progressBar3"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressBar2" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Start Task"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressBar3" />
</androidx.constraintlayout.widget.ConstraintLayout>