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.
-
Right Click on the value folder and go New>Android XML Resource File
-
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.
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Sunidhi Sharma
An ardent computer science enthusiast working in the field of Android application development.