Tutorials  /  Linux Basics

Android ProgressBar Tutorial in Kotlin

Ccentron Redaktion · October 2024 ·4 min read ·Linux Basics, Tutorial

In this tutorial, we’ll discuss and implement ProgressBar in our Android Application using Kotlin.

What is a ProgressBar?

ProgressBar UI element is used to display the Progress on the app screen. We can use a ProgressBar to show the download/upload progress on the app screen.

VM

Matching infrastructure at centron

No hardware needed to follow along: ccloud³ VMs with full root access start at €3.12 per month, billed by the hour and ready in seconds. Rent a cloud server →

Android ProgressBar Types

There are two types of Progress Bar.

  • Determinate ProgressBar - This is used when you can track and show the progress completed.
  • Indeterminate ProgressBar - This one goes infinitely until stopped.

A ProgressDialog would hold a ProgressBar inside an Alert Dialog. ProgressDialog is now deprecated since it isn’t a good idea to show long progress in a dialog while blocking the screen.

ProgressBar Attributes

Some of the important attributes of ProgressBar are:

  • android:indeterminate - used to specify the boolean value indicating the type of the ProgressBar
  • android:max - The upper limit of the progress
  • android:min - The lower limit of the progress
  • android:progress - The steps by which the progress would be incremented.
  • android:minWidth and minHeight - Used to define the dimensions of the ProgressBar
  • android:progressBarTint - The tint color of the progress completed of the ProgressBar
  • android:progressBarBackgroundTint - The tint color of the progress completed of the ProgressBar
  • style - Used to set the style of the ProgressBar. By default it is circular. We can set the style as @style/Widget.AppCompat.ProgressBar.Horizontal for the Horizontal ProgressBar
  • android:progressDrawable - Is used to set a drawable for the progress.
  • android:secondaryProgress - Indicates the secondary progress value. This is used when we want to show the sub-downloads/subtasks progress.

The default tint colors are set to the colorAccent defined in the styles.xml.

Android ProgressBar XML Layout

A basic circular indeterminate ProgressBar XML layout looks like this:

Code
<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:minHeight="50dp"
    android:minWidth="50dp" />

In the following section, we’ll implement various types of ProgressBars in our Android app using Kotlin.

1. Android ProgressBar XML Layout Code

The code for the activity_main.xml layout is as follows.

Code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minHeight="50dp"
        android:minWidth="50dp" />

    <ProgressBar
       
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="true"
        android:minHeight="50dp"
        android:minWidth="200dp" />

    <TextView
        android:id="@+id/textViewHorizontalProgress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="0" />

    <ProgressBar
        android:id="@+id/progressBarHorizontal"
       
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:max="100"
        android:minHeight="50dp"
        android:minWidth="200dp"
        android:progress="1"
        android:progressBackgroundTint="@android:color/darker_gray"
        android:progressTint="@color/colorPrimary" />

    <Button
        android:id="@+id/btnProgressBarHorizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="horizontalDeterminate"
        android:text="DETERMINATE HORIZONTAL PROGRESS BAR" />

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ProgressBar
            android:id="@+id/progressBarSecondary"
           
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:minHeight="150dp"
            android:padding="8dp"
            android:minWidth="150dp"
            android:progressDrawable="@drawable/progress_states" />

        <TextView
            android:id="@+id/textViewPrimary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textColor="#000" />

        <TextView
            android:id="@+id/textViewSecondary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="25dp"
            android:layout_below="@+id/progressBarSecondary"
            android:textColor="@color/colorPrimaryDark" />

    </RelativeLayout>

    <Button
        android:id="@+id/btnProgressBarSecondary"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="DETERMINATE SECONDARY PROGRESS BAR" />

</LinearLayout>

In the last progress bar, we’ve set a progress drawable on the horizontal ProgressBar. The drawable.xml file is progress_states.xml.

Code
<?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 android:shape="oval">
            <stroke
                android:width="4dp"
                android:color="@color/colorPrimary" />
            <solid android:color="@android:color/white" />
        </shape>
    </item>
    <item android:id="@android:id/secondaryProgress">
        <clip
            android:clipOrientation="vertical"
            android:gravity="bottom">
            <shape android:shape="oval">
                <stroke
                    android:width="4dp"
                    android:color="@android:color/black" />
                <solid android:color="@android:color/white" />
            </shape>
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip
            android:clipOrientation="vertical"
            android:gravity="bottom">
            <shape android:shape="oval">
                <stroke
                    android:width="4dp"
                    android:color="@color/colorAccent" />
                <solid android:color="#F288F8" />
            </shape>
        </clip>
    </item>
</layer-list>

In this drawable, we’ve created different states of the drawable. All are circular shaped and each layer would be displayed for the different states - idle, secondary progress, primary progress.

2. Kotlin Main Activity Code

Let’s look at the MainActivity.kt Kotlin class code.

Go
package net.androidly.androidlyprogressbar

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

class MainActivity : AppCompatActivity() {

    var isStarted = false
    var progressStatus = 0
    var handler: Handler? = null
    var secondaryHandler: Handler? = Handler()
    var primaryProgressStatus = 0
    var secondaryProgressStatus = 0

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

        handler = Handler(Handler.Callback {
            if (isStarted) {
                progressStatus++
            }
            progressBarHorizontal.progress = progressStatus
            textViewHorizontalProgress.text = "${progressStatus}/${progressBarHorizontal.max}"
            handler?.sendEmptyMessageDelayed(0, 100)

            true
        })

        handler?.sendEmptyMessage(0)

        btnProgressBarSecondary.setOnClickListener {
            primaryProgressStatus = 0
            secondaryProgressStatus = 0

            Thread(Runnable {
                while (primaryProgressStatus < 100) {
                    primaryProgressStatus += 1

                    try {
                        Thread.sleep(1000)
                    } catch (e: InterruptedException) {
                        e.printStackTrace()
                    }

                    startSecondaryProgress()
                    secondaryProgressStatus = 0

                    secondaryHandler?.post {
                        progressBarSecondary.progress = primaryProgressStatus
                        textViewPrimary.text = "Complete $primaryProgressStatus% of 100"

                        if (primaryProgressStatus == 100) {
                            textViewPrimary.text = "All tasks completed"
                        }
                    }
                }
            }).start()
        }
    }

    fun startSecondaryProgress() {
        Thread(Runnable {
            while (secondaryProgressStatus < 100) {
                secondaryProgressStatus += 1

                try {
                    Thread.sleep(10)
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }

                secondaryHandler?.post {
                    progressBarSecondary.setSecondaryProgress(secondaryProgressStatus)
                    textViewSecondary.setText("Current task progress\n$secondaryProgressStatus% of 100")

                    if (secondaryProgressStatus == 100) {
                        textViewSecondary.setText("Single task complete.")
                    }
                }
            }
        }).start()
    }

    fun horizontalDeterminate(view: View) {
        isStarted = !isStarted
    }

}

The horizontalDeterminate Kotlin function is triggered when the first button is clicked. It is used to start/stop Horizontal Android ProgressBar. A Handler is associated with a single thread. It is used to send messages to the Thread. The btnProgressBarSecondary click triggers the second progress bar. We have created two handlers - one for the normal progress and second for the subtasks. In each of them, we are setting the thread to sleep. For the secondary thread, the sleep time is 1/100 of the primary progress thread. The progress value is displayed on the TextView.

Jetzt 200 € Guthaben sichern

Testen Sie Ihr Setup auf ccloud³

Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.

centron Redaktion Technische Redaktion

Das Redaktionsteam von centron schreibt Anleitungen aus dem Betriebsalltag: getestet auf unserer eigenen Plattform, betrieben im Rechenzentrum in Hallstadt bei Bamberg.

Kategorie Linux Basics
Teilen
Noch offene Fragen?

Unser Team hilft Ihnen bei Ihrem konkreten Setup weiter – von Menschen, die die Plattform selbst betreiben.

War dieses Tutorial hilfreich?

Ihre Antwort wird anonym gespeichert und hilft uns, die Tutorials zu verbessern.

Kommentare

Noch keine Kommentare – stellen Sie die erste Frage zu diesem Tutorial.

Zum Kommentieren anmelden

Kommentare stehen centron-Kunden offen. Melden Sie sich in Ihrem Konto an, um eine Frage zu diesem Tutorial zu stellen.

Weiterlesen

Das könnte Sie auch interessieren

Jetzt kostenlos anfangen

Melden Sie sich an und erhalten Sie in den ersten 60 Tagen ein Guthaben von 200 € bei centron.

Dieses Werbeangebot gilt nur für neue Konten. Angebot ausschließlich für Gewerbetreibende.

Jetzt loslegen Sales kontaktieren