Display progress using ProgressBar – Android

Display progress using ProgressBar – Android

The scenario is to display progress in a ProgressBar and the percentage in a TextView. Once the download is complete, hide the ProgressView and display a message in the TextView. To reference the XML elements we will be using ViewBinding.

Create Android Application Project

Create Android Application Project with following properties:

New Project TemplateEmpty Activity
Project NameProgress Demo
Package Namecom.pcsalt.example.progressdemo
LanguageKotlin
Minimum SDKAPI 21 : 5.0 (Lollipop)
Use legacy android.support librariesUncheck

Prepare layout screens

To display the progress we are going to use one TextView and obviously one ProgressBar. The TextView will display the progress percent and same will reflect in the ProgressBar. And once the progress reaches 100% we are going to hide the ProgressView and display a message in the TextView.

Note: Make sure that you have given Horizontal style to the ProgressBar i.e. @style/Widget.AppCompat.ProgressBar.Horizontal Otherwise it won't work.
Note: Make sure to put max property in ProgressBar. ProgressBar uses value of max and progress to calculate percentage and display the progress. By default the max is set to 100.
<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ProgressBar
        android:id="@+id/pb_details"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:max="100"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_progress" />

</androidx.constraintlayout.widget.ConstraintLayout>

Enable ViewBinding

To enable ViewBinding, open the app level build.gradle i.e. app/build.gradle. In the file put the following in android {} block to enable the ViewBinding. After inserting these lines synchronise the gradle and you are good to go.

android {
    ... other blocks ...
    buildFeatures {
        viewBinding true
    }
}

Get ready with ViewBinding

Since we have enabled ViewBinding, therefore we don’t have to use findViewById() anymore. First we have to get the binding object and that binding object will provide the element reference id from layout file. To do this we have to know the binding class name. The class is autogenerated and it is named using the layout file name. Since our layout file name is activity_main.xml so, the binding class name will be ActivityMainBinding.

Benefit of using ViewBinding is that all layout elements with id will be available as binding property. The binding class will have root property to denote the root layout or the parent layout. This root should be passed into the setContentView() to render the layout file using the ViewBinding.

Note: Double check to see if you are using setContentView(binding.root) instead of setContentView(R.layout.activity_main). Else the listeners and data set using binding properties will not reflect.
private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)
}

Display Progress in ProgressBar

To display progress in a ProgressBar we have to set the progress property of the ProgressBar.

val progress = binding.pbDetails.progress + 10
binding.pbDetails.progress = progress

We will update the TextView and the ProgressBar with the new progress by getting the previous progress from the ProgressBar and adding 10 to it. Ideally if we get percentage we should set the value directly to the ProgressBar’s progress. But to demonstrate the progressing view we are adding 10 to the previous progress.

private fun showProgress() {
handler.postDelayed({
val progress = binding.pbDetails.progress + 10
binding.tvProgress.text = "$progress/100..."
binding.pbDetails.progress = progress

if (progress < 100) {
showProgress()
} else {
binding.tvProgress.text = "Download/Initialization Completed"
binding.pbDetails.visibility = View.GONE
}
}, 900)
}

Complete MainActivity.kt

Here is the complete MainActivity.kt with all the imports used in the class.

package com.pcsalt.example.progressdemo

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.pcsalt.example.progressdemo.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

private lateinit var binding: ActivityMainBinding
private var handler = Handler(Looper.getMainLooper())

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

binding.tvProgress.text = "0/100..."
showProgress()
}

private fun showProgress() {
handler.postDelayed({
val progress = binding.pbDetails.progress + 10
binding.tvProgress.text = "$progress/100..."
binding.pbDetails.progress = progress

if (progress < 100) {
showProgress()
} else {
binding.tvProgress.text = "Download/Initialization Completed"
binding.pbDetails.visibility = View.GONE
}
}, 900)
}
}

Screenshots

Following are the screenshots of the application.

Points to remember

  1. ProgressBar displays progress if and only if style is set to Horizontal i.e. style="@style/Widget.AppCompat.ProgressBar.Horizontal"
  2. max property should be set either using XML’s property android:max="<value>" or using ProgressBar class’s instance method ProgressBar#setMax(int)
  3. Default value of max is 100 and progress percentage will be calculated.
  4. Double check to see if you are using setContentView(binding.root) instead of setContentView(R.layout.activity_main). Else the listeners and data set using binding properties will not reflect.

Video Tutorial on YouTube

Download Source Code

The complete source code is pushed to GitHub repo. Browse it by clicking the octocat icon.

Browse source code on GitHub