This code snippet showcases how to implement a progress bar with a corresponding percentage counter in an Android application written in Kotlin. It simulates a file download scenario to demonstrate the progress functionality.
The code consists of two parts: the Kotlin class (MainActivity.kt
) handling the logic and the layout file (activity_main.xml
) defining the user interface elements.
Breakdown of the Code
The MainActivity.kt
class manages the user interaction and progress updates:
- Initialization: It retrieves references to the button, text view, and progress bar from the layout using
findViewById
. Additionally, aHandler
object is created to update the UI thread from the background thread. - Button Click Listener: Clicking the button triggers the following actions:
- Disables the button to prevent multiple clicks.
- Initializes variables for progress status and the total number of files to download (randomly generated).
- Sets the maximum value of the progress bar based on the total files.
- Background Thread: A new thread is created to simulate the download process. Inside the thread:
- A loop iterates until all files are downloaded (based on
progressStatus
). - The progress is incremented, and the thread sleeps for a short duration (simulating download time).
- Using the
Handler.post
method, the UI thread is updated with:- The progress bar value set to the current progress.
- The percentage calculated based on downloaded files and total files.
- The text view updated with the download status.
- Once the download is complete (progress reaches the total files), the button is re-enabled.
- A loop iterates until all files are downloaded (based on
The activity_main.xml
defines the layout:
- It uses a ConstraintLayout to position the UI elements.
- It includes a TextView to display the download status.
- It has a ProgressBar with a horizontal style to visualize the download progress.
- Finally, a Button initiates the download process.
MainActivity.kt
package com.cfsuman.kotlintutorials
import android.app.Activity
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 kotlin.random.Random
class MainActivity : Activity() {
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)
// Initialize a new Handler instance
val handler = Handler(Looper.getMainLooper())
// Set a click listener for button widget
button.setOnClickListener{
// Disable the button itself
it.isEnabled = false
// Variable to hold progress status
var progressStatus = 0;
// Set up progress bar on initial stage
progressBar.progress = 0
// Generate random number of files to download
val filesToDownload= Random.nextInt(50,200)
// set up max value for progress bar
progressBar.max = filesToDownload
// Start the lengthy operation in a background thread
Thread {
while (progressStatus < filesToDownload) {
// Update the progress status
progressStatus += 1
// Try to sleep the thread for 100 milliseconds
try {
Thread.sleep(100)
} catch (e: InterruptedException) {
e.printStackTrace()
}
handler.post {
// Update the progress bar
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%)"
// When the task done
if (progressStatus == filesToDownload) {
// Enable the button
button.isEnabled = true
}
}
}
}.start() // Start the operation
}
}
}
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="36dp"
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="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<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/progressBar" />
</androidx.constraintlayout.widget.ConstraintLayout>