Implementing DialogFragment in Android

Using a dialog over some existing Activity is a very interesting thing to have in our Android Application. We use dialogs to have a quick implementation of some feature in our application without creating an Activity. For example, whenever you are connecting to a new wifi network then after selecting the wifi network, a Dialog will be opened and you can enter that password in the opened dialog and submit the details. Following is the image of the same:

One of the popular implementations of Dialogs is Alert Dialog. Alert Dialogs are used to alert the user before performing a particular task. For example, if you want to delete some images from the Gallery, then the Gallery app will alert you about the fact that by pressing the OK button which is the positivity button, in this case, the image will be deleted permanently.

So, in this blog, we will learn how to make Dialogs using the DialogFragment in Android. So, let’s get started.

What is DialogFragment?

In a very simple sentence, a Dialog Fragment is a fragment that is used to make Dialogs that floats on some Activity.

DialogFragment is a utility class which extends the Fragment class. So, a DialogFragment displays or shows a Dialog but inside a Fragment i.e. all the information regarding the Dialog or the data associated with the Dialog will be stored or managed in the Fragment only. You can use the DialogFragment in API level 11 or higher.

Since DialogFragment is associated with Fragment, so it has it’s own Life Cycle and now the Activity need not manage the lifecycle of Dialogs. Due to this reason, DialogFragments are recommended to be used while implementing Alert Dialog or any other type of Dialogs in Android.

If you are having a good knowledge of Fragments, then it will be very easy for you to implement the DialogFragment but if you don’t know Fragments or you hate Fragments then don’t worry, we will learn how to use the DialogFragment in the best possible way.

Creating a Custom Dialog using DialogFragment

You can create your own Custom Dialog using the DialogFragment by just extending the DialogFragment() and then making the Dialog by using onCreateView() method of DialogFragment. Following is an example of the same:

class MyDialog : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?):Dialog {
       //some code goes here
   }
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    
    //here fragment_my_dialog is the UI of Custom Dialog
    
    return inflater.inflate(R.layout.fragment_my_dialog, container, false)
    }
}

After creating the custom Fragment for the Dialog, all you need to do is call the Fragment form your MainActivity or form desired activity and use the show() method to show the Dialog. Following is an exmaple, where I am using the above MyDialog Fragment to show the Dialog:

val fragmentTransaction = supportFragmentManager.beginTransaction()
val prev = supportFragmentManager().findFragmentByTag("dialog")
if (prev != null) {
    fragmentTransaction.remove(prev)
}
fragmentTransaction.addToBackStack(null)
val dialogFragment = MyDialog() //here MyDialog is my custom dialog
dialogFragment.show(fragmentTransaction, "dialog")

You can use the Dialog in three different ways:

  1. You can simply show the dialog on the same Activity. All you need to do is put some space for the Fragment in your Activity and after that replace that Fragment with your custom Dialog Fragment.
  2. The second way of showing the Dialog Fragment is to open the Fragment in full screen i.e. your dialog will float over the existing Activity but will occupy the whole screen.
  3. The last and the most famous way of showing the Dialog is by showing it like some Alert Dialog or Progress Dialog.

So, let’s move on to implement the above three ways by making a project.

Implementation of DialogFragment

Create a new project in Android Studio and choose the Empty Activity template. In my case, the name of the Project is DialogFragment.

After creating the project, you will be having two files i.e. MainActivity.kt and activity_main.xml file. Our next step is to create a Fragment for our Dialog. So, go to your package and right click on it and then select new > Fragment > Fragment(Blank) and then enter the name and click Finish. In my case, the Fragment name is MyDialog. Following is the project structure of my project:

After creating the Fragment in our project, our next step is to create the design for our MainActivity. Here I am making four Buttons, one FrameLayout and one TextView.

Buttons will be used for showing different ways of a Dialog i.e. Dialog in full screen or Dialog like an Alert Dialog or Dialog in the same Activity. While FrameLayout is used to display a dialog in the MainActivity and TextView is used to display the entered data in the Dialog on the TextView. So, here is the code for our activity_main.xml file:

<?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:orientation="vertical"
                tools:context=".MainActivity">


    <FrameLayout
            android:id="@+id/frameLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@+id/btnEmbedDialogFragment"
            android:layout_alignParentTop="true"/>


    <Button
            android:id="@+id/btnEmbedDialogFragment"
            android:layout_width="320dp"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:layout_centerHorizontal="true"
            android:layout_above="@+id/btnDialogFragment"
            android:text="Dialog in Same Page"/>

    <Button
            android:id="@+id/btnDialogFragment"
            android:layout_width="320dp"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_marginTop="8dp"
            android:textSize="16sp"
            android:text="Simple Dialog"/>


    <Button
            android:id="@+id/btnDialogFragmentFullScreen"
            android:layout_width="320dp"
            android:layout_height="wrap_content"
            android:layout_below="@+id/btnDialogFragment"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="8dp"
            android:textSize="16sp"
            android:text="Full Screen Dialog"/>


    <Button
            android:id="@+id/btnAlertDialogFragment"
            android:layout_width="320dp"
            android:layout_height="wrap_content"
            android:layout_below="@+id/btnDialogFragmentFullScreen"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="8dp"
            android:textSize="16sp"
            android:text="Alert Dialog"/>

    <TextView
            android:id="@+id/textView"
            android:layout_width="320dp"
            android:layout_height="wrap_content"
            android:layout_below="@+id/btnAlertDialogFragment"
            android:text="Output will be shown here: "
            android:layout_centerHorizontal="true"/>

</RelativeLayout>

After creating the UI on the MainActivity, our next and the most important task is to create the UI for our Dialog. We will create the desired UI for our Dialog in the fragment_my_dialog.xml file. This is the UI that will be displayed whenever the Dialog will be showed. Following is the code for our fragment_my_dialog.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:padding="10dp">


    <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:text="Enter your Mobile and Password" />


    <EditText
            android:id="@+id/inMobile"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Mobile Number"
            android:inputType="numberDecimal" />

    <EditText
            android:id="@+id/inPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Password"
            android:inputType="textPassword" />

    <Button
            android:id="@+id/btnDone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Done" />
</LinearLayout>

This is a simple form, which takes user mobile number and password and the user entered mobile number will be display on the MainActivity after clicking the Done Button.

After writing the code for the UI part, our next task is to write the code for the Fragment and our MainActivity.

Whenever a DialogFragment class is instantiated, the order of method calls is something like below:

  1. onCreate
  2. onCreateDialog
  3. onCreateView
  4. onViewCreated
  5. onDestroy

The onCreateDialog is overridden to build your own custom Dialog container. So, basically is provides a container to build a Dialog.

The onCreateView is used to supply the contents of the Dialog and this is entirely responsible for drawing the Dialog.

The onViewCreated is called when the Dialog is created. This is used to ensure that the view is created.

The onDestroy is used to destroy the DialogFragement.

So, we have learned various states related to the DialogFragment, now let’s write the code for MyDialog.kt file:

class MyDialog : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?):Dialog {
        if (arguments != null)
        {
            if (arguments?.getBoolean("notAlertDialog")!!)
            {
                return super.onCreateDialog(savedInstanceState)
            }
        }
        val builder = AlertDialog.Builder(activity)
        builder.title = "Alert Dialog"
        builder.message = "Hello! I am Alert Dialog"
        builder.setPositiveButton("Cool", object: DialogInterface.OnClickListener {
            override fun onClick(dialog:DialogInterface, which:Int) {
                dismiss()
            }
        })
        builder.setNegativeButton("Cancel", object: DialogInterface.OnClickListener {
            override fun onClick(dialog:DialogInterface, which:Int) {
                dismiss()
            }
        })
        return builder.create()
    }
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_my_dialog, container, false)
    }
    override fun onViewCreated(view:View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val editText = view.findViewById<EditText>(R.id.inMobile)
        if (arguments != null && !TextUtils.isEmpty(arguments?.getString("mobile")))
            editText.setText(arguments?.getString("mobile"))
        val btnDone = view.findViewById<Button>(R.id.btnDone)
        btnDone.setOnClickListener(object: View.OnClickListener {
            override fun onClick(view:View) {
                val dialogListener = activity as DialogListener
                dialogListener.onFinishEditDialog(editText.text.toString())
                dismiss()
            }
        })
    }
    override fun onResume() {
        super.onResume()
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("Hey", "onCreate")
        var  setFullScreen = false
        if (arguments != null) {
            setFullScreen = requireNotNull(arguments?.getBoolean("fullScreen"))
        }
        if (setFullScreen)
            setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen)
    }
    override fun onDestroyView() {
        super.onDestroyView()
    }
    interface DialogListener {
        fun onFinishEditDialog(inputText:String)
    }
}

After writing the code for the Fragment, our next task is to join this Fragment with some button calls in the MainActivity.kt file. In the MainActivity.kt file, we will handle the three ways of implementing the DialogFragment that was discussed earlier in this blog. So, the code for the MainActivity.kt file is:

class MainActivity: AppCompatActivity(), View.OnClickListener, MyDialog.DialogListener {
    internal lateinit var btnEmbedDialogFragment:Button
    internal lateinit var btnDialogFragment:Button
    internal lateinit var btnDialogFragmentFullScreen:Button
    internal lateinit var btnAlertDialogFragment:Button
    internal lateinit var textView:TextView
    override fun onCreate(savedInstanceState:Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        textView = findViewById(R.id.textView)
        btnEmbedDialogFragment = findViewById(R.id.btnEmbedDialogFragment)
        btnDialogFragment = findViewById(R.id.btnDialogFragment)
        btnDialogFragmentFullScreen = findViewById(R.id.btnDialogFragmentFullScreen)
        btnAlertDialogFragment = findViewById(R.id.btnAlertDialogFragment)
        btnEmbedDialogFragment.setOnClickListener(this)
        btnDialogFragment.setOnClickListener(this)
        btnDialogFragmentFullScreen.setOnClickListener(this)
        btnAlertDialogFragment.setOnClickListener(this)
    }
    override fun onClick(view:View) {
        when (view.id) {
            R.id.btnEmbedDialogFragment -> {
                val dialogFragment = MyDialog()
                val ft = supportFragmentManager.beginTransaction()
                ft.replace(R.id.frameLayout, dialogFragment)
                ft.commit()
            }
            R.id.btnDialogFragment -> {
                val dialogFragment = MyDialog()
                val bundle = Bundle()
                bundle.putBoolean("notAlertDialog", true)
                dialogFragment.arguments = bundle
                val ft = supportFragmentManager.beginTransaction()
                val prev = supportFragmentManager.findFragmentByTag("dialog")
                if (prev != null)
                {
                    ft.remove(prev)
                }
                ft.addToBackStack(null)
                dialogFragment.show(ft, "dialog")
            }
            R.id.btnDialogFragmentFullScreen -> {
                val dialogFragment = MyDialog()
                val bundle = Bundle()
                bundle.putString("mobile", "0123456789")
                bundle.putBoolean("fullScreen", true)
                bundle.putBoolean("notAlertDialog", true)
                dialogFragment.arguments = bundle
                val ft = supportFragmentManager.beginTransaction()
                val prev = supportFragmentManager.findFragmentByTag("dialog")
                if (prev != null) {
                    ft.remove(prev)
                }
                ft.addToBackStack(null)
                dialogFragment.show(ft, "dialog")
            }
            R.id.btnAlertDialogFragment -> {
                val dialogFragment = MyDialog()
                val ft = supportFragmentManager.beginTransaction()
                val prev = supportFragmentManager.findFragmentByTag("dialog")
                if (prev != null)
                {
                    ft.remove(prev)
                }
                ft.addToBackStack(null)
                dialogFragment.show(ft, "dialog")
            }
        }
    }
    override fun onFinishEditDialog(inputText:String) {
        if (TextUtils.isEmpty(inputText))
        {
            textView.text = "Please enter Mobile Number"
        }
        else
            textView.text = "Number entered: " + inputText
    }
}

In the above code, we are creating different types of Fragments on different Button clicks. You can use your own way of implementing the DialogFragment in your Android Application.

Conclusion

In this blog, we learned how to implement DialogFragment in our Android Application. We saw that the traditional Alert Dialogs are no longer recommended. So, we need to use the DialogFragment to implement Dialogs. We did one example on DialogFragment to have a clear understanding of the same.

That’s it for this blog. Keep Learning :)

Team MindOrks!