This code demonstrates two methods for changing the color of an indeterminate progress bar in an Android application written in Kotlin. The code includes a button click listener that simulates a downloading process with a progress bar and text update.
Breakdown
The MainActivity.kt
file handles the Activity logic:
- Setting Up References: It retrieves references to UI elements like buttons, text views, and progress bars from the layout file.
- Changing Indeterminate Progress Bar Color (Method 1):
- Sets the
indeterminateTintList
property of a progress bar to aColorStateList
with a specific color (red in this case). - Sets the
indeterminateTintMode
property toPorterDuff.Mode.SRC_IN
to apply the tint color.
- Sets the
- Changing Indeterminate Progress Bar Color (Method 2):
- Checks the Android SDK version.
- For API level 29 (Android Q) and above, it uses
BlendModeColorFilter
with the desired color (blue) andBlendMode.SRC_IN
for tinting. - For versions below API 29, it uses the older
setColorFilter
method with the same color andPorterDuff.Mode.SRC_IN
.
- Button Click Listener:
- Simulates a download process:
- Disables the button to prevent multiple clicks.
- Shows all progress bars using
TransitionManager
for animation. - Resets progress and generates a random number of files to download.
- Sets the maximum value of the progress bar based on the random number.
- Starts a background thread to simulate the download progress.
- The background thread:
- Increments the progress counter.
- Sleeps the thread for a short duration to simulate download time.
- Updates the progress bar and text view on the main thread using
Handler.post
. - Calculates the download percentage.
- Updates the text view with download status.
- Once the download is complete (progress reaches the max value), it enables the button again and hides all progress bars with animation.
- Simulates a download process:
The activity_main.xml
file defines the layout for the Activity:
- It includes a ConstraintLayout to position the UI elements.
- It has a TextView to display download status.
- It defines four progress bars with indeterminate mode (they show animation without a defined progress).
- It has a button to initiate the download process.
MainActivity.kt
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.view.View
import android.widget.Button
import android.widget.ProgressBar
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.transition.TransitionManager
import kotlin.random.Random
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 rootLayout = findViewById<ConstraintLayout>(R.id.rootLayout)
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)
val progressBar4 = findViewById<ProgressBar>(R.id.progressBar4)
// change indeterminate progressbar color (tint) programmatically
progressBar3.indeterminateTintList = ColorStateList
.valueOf(Color.RED)
progressBar3.indeterminateTintMode = PorterDuff.Mode.SRC_IN
// another way to change indeterminate progress bar color
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
progressBar4.indeterminateDrawable.colorFilter =
BlendModeColorFilter(Color.BLUE, BlendMode.SRC_IN)
}else {
progressBar4.indeterminateDrawable
.setColorFilter(Color.BLUE, PorterDuff.Mode.SRC_IN)
}
// button click listener
button.setOnClickListener {
button.isEnabled = false
TransitionManager.beginDelayedTransition(rootLayout)
progressBar.visibility = View.VISIBLE
progressBar2.visibility = View.VISIBLE
progressBar3.visibility = View.VISIBLE
progressBar4.visibility = View.VISIBLE
// set up progress bar on initial stage
progressBar.progress = 0
progressStatus = 0
// generate random number of files to download
val filesToDownload= Random.nextInt(200,500)
// set up max value for progress bar
progressBar.max = filesToDownload
Thread(Runnable {
while (progressStatus < filesToDownload){
// update progress status
progressStatus +=1
// sleep the thread for 50 milliseconds
Thread.sleep(50)
// update the progress bar
handler.post {
//progressBar.progress = progressStatus
// calculate the percentage
val percentage = ((progressStatus.toDouble()
/ filesToDownload) * 100).toInt()
// update the text view
textView.text = "Downloaded $progressStatus of " +
"$filesToDownload files ($percentage%)"
if (progressStatus == filesToDownload){
button.isEnabled = true
TransitionManager
.beginDelayedTransition(rootLayout)
progressBar.visibility = View.INVISIBLE
progressBar2.visibility = View.INVISIBLE
progressBar3.visibility = View.INVISIBLE
progressBar4.visibility = View.INVISIBLE
}
}
}
}).start()
}
}
}
activity_main.xml
<?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"
android:visibility="invisible"
android:indeterminate="true"
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"
android:visibility="invisible"
android:indeterminate="true"
android:indeterminateTint="#00A86B"
android:indeterminateTintMode="src_in"
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"
android:visibility="invisible"
android:indeterminate="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressBar2" />
<ProgressBar
android:id="@+id/progressBar4"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:visibility="invisible"
android:indeterminate="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/progressBar3" />
<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/progressBar4" />
</androidx.constraintlayout.widget.ConstraintLayout>