How to Create Custom Progress Dialog in Android Using Kotlin

Posted By : Sunidhi Sharma | 19-Aug-2019

Overview

 

Progress Dialog is the dialog with a progress indicator and text message. It can be used when you’re doing some task on your app that needs time to complete, like sending or retrieving data from a server, and you don’t want your users staring at the screen without giving them feedback that something is happening in the background.

In this tutorial, we'll see how one can make custom Progress Dialog for your Android app.

 

Requirements

 

1. Android Studio v3 or above.

2. Android Gradle version 3.4 or above.

3. A new Android Project with Kotlin Support.

 

Let’s get Started

 

In this blog post, we’re going to build our custom Progress Dialog with Kotlin. We will be using CardView to have nice rounded corners in our Progress Dialog. If you don’t want this, just skip this step and use RelativeLayout instead.

 

STEP 1: Adding Gradle Dependencies for CardView

 

Add the CardView dependency in your build.gradle file like that:

dependencies {
implementation 'androidx.cardview:cardview:1.0.0'
}

 

STEP 2: Adding Custom Progress Bar to our app

 

First, let’s create our custom progress bar layout (progress_bar.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"
   android:id="@+id/cp_bg_view"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="#00000000"
   app:layout_constraintBottom_toBottomOf="parent"
   app:layout_constraintEnd_toEndOf="parent"
   app:layout_constraintStart_toStartOf="parent"
   app:layout_constraintTop_toTopOf="parent">
   <androidx.cardview.widget.CardView
   	android:id="@+id/cp_cardview"
   	android:layout_width="150dp"
   	android:layout_height="150dp"
   	app:cardBackgroundColor="#00000000"
   	app:cardCornerRadius="16dp"
   	app:cardElevation="0dp"
   	app:cardMaxElevation="0dp"
   	app:layout_constraintBottom_toBottomOf="parent"
   	app:layout_constraintEnd_toEndOf="parent"
   	app:layout_constraintStart_toStartOf="parent"
   	app:layout_constraintTop_toTopOf="parent">
   	<androidx.constraintlayout.widget.ConstraintLayout
       	android:id="@+id/cp_view"
       	android:layout_width="match_parent"
       	android:layout_height="match_parent"
       	android:layout_gravity="center"
       	android:gravity="center">
       	<ProgressBar
           	android:id="@+id/cp_pbar"
           	android:layout_width="match_parent"
           	android:layout_height="45dp"
           	android:layout_gravity="center"
           	android:layout_marginTop="8dp"
           	android:layout_marginBottom="8dp"
           	app:layout_constraintBottom_toBottomOf="parent"
           	app:layout_constraintEnd_toEndOf="parent"
           	app:layout_constraintStart_toStartOf="parent"
           	app:layout_constraintTop_toTopOf="parent" />
       	<TextView
           	android:id="@+id/cp_title"
           	android:layout_width="wrap_content"
           	android:layout_height="wrap_content"
           	android:layout_marginStart="8dp"
           	android:layout_marginEnd="8dp"
           	android:layout_marginBottom="15dp"
           	android:text=""
           	android:textColor="@android:color/white"
           	android:textStyle="bold"
           	app:layout_constraintBottom_toBottomOf="parent"
           	app:layout_constraintEnd_toEndOf="parent"
           	app:layout_constraintStart_toStartOf="parent" />
   	</androidx.constraintlayout.widget.ConstraintLayout>
   </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

 

STEP 3: Binding Kotlin with XML

 

Now, let’s create the Kotlin class like the following code:

class CustomProgressBar {

lateinit var dialog: Dialog

fun show(context: Context): Dialog {

return show(context, null)

}

fun show(context: Context, title:CharSequence?): Dialog {

val inflator = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

val view = inflator.inflate(R.layout.progress_bar, null)

if (title != null) {

view.cp_title.text = title

}

view.cp_bg_view.setBackgroundColor(Color.parseColor("#60000000")) //Background Color

view.cp_cardview.setCardBackgroundColor(Color.parseColor("#70000000")) //Box Color

setColorFilter(view.cp_pbar.indeterminateDrawable,

ResourcesCompat.getColor(context.resources, R.color.colorPrimary, null)) //Progress Bar Color

view.cp_title.setTextColor(Color.WHITE) //Text Color

dialog = Dialog(context, R.style.CustomProgressBarTheme)

dialog.setContentView(view)

dialog.show()

return dialog

}

fun setColorFilter(@NonNull drawable: Drawable, color:Int) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

drawable.colorFilter = BlendModeColorFilter(color, BlendMode.SRC_ATOP)

} else {

@Suppress("DEPRECATION")

drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)

}

}

}

 

STEP 4: Adding the themes and styles

 

If you run the project, you will get an error about line 21. That’s because our custom Progress Dialog uses a theme that makes it transparent over the current screen.

The theme needs to be in style.xml and styles.xml (v21) files.

If you don’t have the second one in your project, which is for the devices with Android 5.0 (API 21), you can add it by following the steps below.

  1. Right Click on the value folder and go New>Android XML Resource File

  2. Set the following:
    File name: styles
    Source set: main
    Available qualifiers: Version and press the >> button and write 21 in the Platform API level field.
    Press OK

Creating styles.xml (v21) file

After that, paste the following code in both files (styles.xml and styles.xml (v21) ):

<resources xmlns:tools="http://schemas.android.com/tools">

   <style name="CustomProgressBarTheme">

   	<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>

   	<item name="android:windowBackground">@android:color/transparent</item>

   </style>

</resources>

If you want the status bars icons to be black, just change the item android:windowLightStatusBar to true

In this example, we have a Button to show the Custom Progress Bar and we automatically dismiss it after 4 seconds, just to show you how it works.

Let’s create the layout for our MainActivity (activity_main.xml) :

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

   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:background="@color/colorPrimary"

   android:gravity="center"

   tools:context=".MainActivity">

   <Button

   	android:id="@+id/start_btn"

   	android:layout_width="wrap_content"

   	android:layout_height="wrap_content"

   	android:background="@color/colorPrimaryDark"

   	android:padding="15dp"

   	android:text="Start Custom Progress Bar"

   	android:textAllCaps="false"

   	android:textColor="@android:color/white"

   	android:textStyle="bold" />

</RelativeLayout>

 

STEP 5: Coding the MainActivity

 

To your MainActivity.kt, paste the following code:

class MainActivity : AppCompatActivity() {

val progressBar = CustomProgressBar()

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

start_btn.setOnClickListener {

// Show progress bar

progressBar.show(this,"Please Wait...")

Handler().postDelayed({

//Dismiss progress bar after 4 seconds

progressBar.dialog.dismiss()

}, 4000)

}

}

}

Here we show our Custom Progress Bar with the text “Please Wait”. If you just want to have only a progress indicator without any text, you can do it by changing line 11 with the following code:

//Progress Bar with Text

progressBar.show(this,"Please Wait...")

//Progress Bar without Text

progressBar.show(this)

Now let’s run it!!

 

STEP 6: Trying to solve the problems

 

Oops!, our Custom Progress Dialog’s transparent black background doesn’t look like to be over our status bar in devices with Android 5.0 and above. Let’s try to fix!

 

Custom Progress Dialog’s transparent black background it’s not over the status bar

Let’s make the status bar translucent and set it to true and see if it’s going to work. To do this, replace the code in our style.xml (v21) file with this:

<resources xmlns:tools="http://schemas.android.com/tools">

   <style name="CustomProgressBarTheme">

       <item name="android:windowTranslucentStatus">true</item>

       <item name="android:windowLightStatusBar" tools:targetApi="m">false</item>

       <item name="android:windowBackground">@android:color/transparent</item>

   </style>

</resources>

Wow, it seems to work but… don’t you think it looks darker than we expect? 

Using android:windowTranslucentStatus makes status bar darker

Take you the HEX Color Code you have for your status bar and replace your content background with it, or somewhere where our Custom Progress Bar shows over it. In our example:

Before we replace our status bar color to the background

After we replace the status bar color to our background

Now press the button to run our Custom Progress Bar and while it’s running take a screenshot like that:

Now, let’s go back to our style.xml (v21) file and add to our theme an item with a name "android:statusBarColor"and paste our HEX Color Code, like that:

 
<resources xmlns:tools="http://schemas.android.com/tools">
   <style name="CustomProgressBarTheme">
   	<item name="android:statusBarColor">#631128</item>
   	<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
   	<item name="android:windowBackground">@android:color/transparent</item>
   </style>
</resources>

Let’s run it and…boom!!

 

Conclusion

 

In this blog post, we covered how one can design their custom progress bar in their Android application using Kotlin. You can also add more customizations as per your and application's needs to create a beautiful UI following the same example.

About Author

Author Image
Sunidhi Sharma

An ardent computer science enthusiast working in the field of Android application development.

Request for Proposal

Name is required

Comment is required

Sending message..