Android Show Busy/Loading and Prevent Touch (using DialogFragment) - Kotlin

Dialog with transparent background and disable black opacity

Solution 1

You can disable activity and show/hide a ProgressBar.

Solution 2: Dialog

The inconvinience with Solution 1 is that you always need to embeded ProgressBar into the current layout.

This solution will use a DialogFragment to display the ProgressBar.

  • Dialog comes with white inner background and black outer overlay with opacity, and prevent user from touching the activity.
  • Make the white background transparent
  • Remove outer black overlay of fragment
  • Prevent dialog dismiss by user touch
class BusyDialogFragment: DialogFragment() {    companion object {        private const val FRAGMENT_TAG = "busy"        fun newInstance() = BusyDialogFragment()        fun show(supportFragmentManager: FragmentManager): BusyDialogFragment {            val dialog = BusyDialogFragment.newInstance()            // prevent dismiss by user click            dialog.isCancelable = false            dialog.show(supportFragmentManager, FRAGMENT_TAG)            return dialog        }    }    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {        // return super.onCreateView(inflater, container, savedInstanceState)        // make white background transparent        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))        return activity!!.layoutInflater.inflate(R.layout.busy, container)    }    override fun onStart() {        super.onStart()        // remove black outer overlay, or change opacity        dialog?.window?.also { window ->            window.attributes?.also { attributes ->                attributes.dimAmount = 0.1f                window.attributes = attributes            }        }    }}

Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

Usage: Show dialog

val busyDialog = BusyDialogFragment.show(supportFragmentManager)

Hide dialog

busyDialog.dismiss()

Use function reference to automatically show and dismiss dialog

class BusyDialog: DialogFragment() {    companion object {        ...        fun <R> show(fragmentManager: FragmentManager, block: () -> R): R {            val dialog = show(fragmentManager)            return block().apply {                dialog.dismiss()            }        }    }

Usage

val result = BusyDialog.show(fragmentManager!!) {    // do something}

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.