Android ProgressBar in Determinate Mode with Kotlin

Android ProgressBar – Kotlin Example : In this Android Tutorial, we shall learn to indicate the progress of an operation using ProgressBar. We shall use an Example Android Application with dummy operation whose progress has to indicated to user.

A determinate Android ProgressBar is useful when the app can measure how much work is already complete. Common examples include file downloads, uploads, form processing, database migration, or any task where you can calculate progress as a number.

ProgressBar could be used both Determinate and Indeterminate progress of a task.

  • Indeterminate ProgressBar is used when you cannot estimate or track the progress of a task. By default ProgressBar is in Indeterminate mode.
  • Determinate ProgressBar is used when you can estimate or track the progress of a task. To make ProgressBar determinate, add progress property, android:progress=”0″ , in the layout file for ProgressBar View.

In this tutorial, we shall see an example for Determinate ProgressBar. In our next tutorial, we shall learn Android Indeterminate ProgressBar

Android ProgressBar - Kotlin Example

Set ProgressBar Progress Value from Kotlin

Progress of ProgressBar can be set using progress property as shown below :

</>
Copy
progressBar.progress = 55

The value provided for the property is the percentage. If 55 is assigned to progress, then 55% of the ProgressBar would be marked with progress.

This percentage explanation is correct when the ProgressBar maximum value is 100. ProgressBar actually compares progress with max. If android:max="200" and progressBar.progress = 50, then the visible progress is 25% because 50 is one fourth of 200.

</>
Copy
<ProgressBar
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:id="@+id/progressBar1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:max="100"
    android:progress="0" />

Android ProgressBar Kotlin Example Project Details

Following are the details of the Android Application we created for this example.

Application NameProgressBarExample
Company nametutorialkart.com
Minimum SDKAPI 21: Android 5.0 (Lollipop)
ActivityEmpty Activity

Create an Android Application with Kotlin Support with above details and keeping rest to default. Replace activity_main.xml and MainActivity.kt with the following content.

activity_main.xml for Horizontal Determinate ProgressBar

The layout contains a button and a horizontal ProgressBar. The horizontal style is important here because the default ProgressBar style is usually used for circular indeterminate loading.

activity_main.xml

</>
Copy
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context="com.tutorialkart.progressbarexample.MainActivity">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="116dp"
        android:text="Do some stuff" />

    <ProgressBar
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:id="@+id/progressBar1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:progress="0"/>

</LinearLayout>

MainActivity.kt to Increase ProgressBar Value

When the button is clicked, the sample starts a dummy task and increases the ProgressBar value in steps. The old sample below is retained as originally written for this tutorial.

MainActivity.kt

</>
Copy
package com.tutorialkart.progressbarexample

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private var progressBarStatus = 0
    var dummy:Int = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // get the references from layout file
        var btnStartProgress = this.button1
        var progressBar = this.progressBar1

        // when button is clicked, start the task
        btnStartProgress.setOnClickListener { v ->

            // task is run on a thread
            Thread(Runnable {
                // dummy thread mimicking some operation whose progress can be tracked
                while (progressBarStatus < 100) {
                    // performing some dummy operation
                    try {
                        dummy = dummy+25
                        Thread.sleep(1000)
                    } catch (e: InterruptedException) {
                        e.printStackTrace()
                    }
                    // tracking progress
                    progressBarStatus = dummy

                    // Updating the progress bar
                    progressBar.progress = progressBarStatus
                }

            }).start()
        }
    }
}

Modern Kotlin Version Using findViewById and Main Thread Updates

In newer Android projects, avoid Kotlin synthetic view access because it is no longer the recommended approach. You can use View Binding, Data Binding, or simple findViewById(). Also, update view properties such as progressBar.progress on the main thread.

The following Kotlin example uses the same layout IDs as the XML above, but resets the ProgressBar on every button click and prevents multiple dummy tasks from running at the same time.

</>
Copy
package com.tutorialkart.progressbarexample

import android.os.Bundle
import android.widget.Button
import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    private lateinit var progressBar: ProgressBar
    private lateinit var startButton: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        startButton = findViewById(R.id.button1)
        progressBar = findViewById(R.id.progressBar1)

        startButton.setOnClickListener {
            startDummyTask()
        }
    }

    private fun startDummyTask() {
        startButton.isEnabled = false
        progressBar.max = 100
        progressBar.progress = 0

        Thread {
            var progress = 0

            while (progress < progressBar.max) {
                Thread.sleep(1000)
                progress += 25

                runOnUiThread {
                    progressBar.progress = progress.coerceAtMost(progressBar.max)

                    if (progressBar.progress == progressBar.max) {
                        startButton.isEnabled = true
                    }
                }
            }
        }.start()
    }
}

Key ProgressBar Properties Used in Determinate Mode

ProgressBar propertyPurpose in determinate progress
android:progressInitial progress value in the XML layout.
android:maxMaximum value used to calculate the filled portion of the bar. If not set, 100 is commonly used.
progressBar.progressKotlin property used to update progress while the task is running.
progressBar.maxKotlin property used when the maximum value must be set from code.
style="@android:style/Widget.ProgressBar.Horizontal"Makes the ProgressBar appear as a horizontal bar suitable for determinate progress.

Common Mistakes with Android Determinate ProgressBar in Kotlin

  • Using the default circular ProgressBar for a percentage task: use the horizontal ProgressBar style when the user should see measurable progress.
  • Updating the ProgressBar from a background thread: calculate work in the background, but update UI properties on the main thread.
  • Forgetting to reset progress before starting again: set progressBar.progress = 0 before a new operation starts.
  • Letting progress go beyond max: clamp the value with coerceAtMost(progressBar.max) or check the value before assigning it.
  • Starting multiple tasks from repeated button clicks: disable the button while the current task is running, or cancel the previous task before starting another one.

Android ProgressBar Determinate Mode FAQs

How do I make ProgressBar determinate in Kotlin Android?

Use a horizontal ProgressBar in XML, set an initial android:progress value, and update progressBar.progress from Kotlin as the task advances. For percentage-style progress, keep max as 100.

What is the difference between determinate and indeterminate ProgressBar?

A determinate ProgressBar shows known progress, such as 40 out of 100. An indeterminate ProgressBar only shows that work is happening, without showing how much is complete.

Can I set Android ProgressBar max value other than 100?

Yes. Set android:max in XML or progressBar.max in Kotlin. For example, if max is 1000 and progress is 250, the bar shows 25% completion.

Why is my Android ProgressBar not updating during a background task?

The task may be running on a background thread while the UI update is not being posted to the main thread. Use runOnUiThread, a main-thread handler, or lifecycle-aware coroutine code to update the ProgressBar safely.

Should I use ProgressBar for file download progress in Kotlin?

Yes, when the total file size is known. Calculate progress from bytes downloaded and total bytes, then assign the calculated value to progressBar.progress. If the total size is unknown, use an indeterminate ProgressBar.

Editorial QA Checklist for this Android ProgressBar Kotlin Tutorial

  • The tutorial clearly explains determinate ProgressBar as measurable progress, not just a loading spinner.
  • The XML example uses @android:style/Widget.ProgressBar.Horizontal for horizontal determinate progress.
  • The Kotlin examples show how progress and max work together.
  • The modern Kotlin note warns against synthetic view access and shows a safer main-thread update pattern.
  • The FAQ answers cover the most common ProgressBar issues: determinate setup, max value, background updates, and download progress.