Tutorial

Android DialogFragment

Published on August 4, 2022
author

Anupam Chugh

Android DialogFragment

In this tutorial, we’ll be discussing what are DialogFragments. We’ll see how they are different from the Dialogs too with the help of a simple android application.

Android DialogFragments

DialogFragment is a utility class which extends the Fragment class. It is a part of the v4 support library and is used to display an overlay modal window within an activity that floats on top of the rest of the content. Essentially a DialogFragment displays a Dialog but inside a Fragment.

Google recommends that we use DialogFragment instead of a simple Alert Dialog builder in the activity.

Why so?

  • DialogFragments have their own lifecycle methods. So the Activity is free from the responsibility of telling the Dialog what to do.
  • No more IllegalStateExceptions and leaked window crashes. This was pretty common when the activity was destroyed with the Alert Dialog still there.

Because DialogFragment is a fragment, it integrates into the activity’s lifecycle and ensures that what’s happening in the dialog window remains consistent. It’s a good practice to use DialogFragments to create dialogs in your android application. Your class must extend DialogFragment with at least onCreateDialog and/or onCreateView implemented. You can create Dialogs using DialogFragment in two ways:

  • onCreateDialog - Here you can create the AlertDialog using the AlertDialog.Builder class.
  • onCreateView - Here you can create a Dialog using a custom view defined.

In order to create a DialogFragment that shows a Dialog, we need to call the method show() on the DialogFragment instance as:

MyDialogFragment dialogFragment = new MyDialogFragment();
FragmentTranscation ft = getSupportFragmentManager().beginTransaction();
Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
if (prev != null) {
   ft.remove(prev);
}
ft.addToBackStack(null);
dialogFragment.show(ft, "dialog");

We can set any tag as the second argument of show(). In order to create a DialogFragment that embeds the dialog in a fragment, we just add the Fragment to the Framelayout as we do it with any Fragment.

Do you know? You can show the custom views in Fragments as well instead of just Dialogs.

When a DialogFragment class is instantiated. Methods are called in the following order:

  • onCreate
  • onCreateDialog
  • onCreateView
  • onViewCreated
  • onDestroy

Passing Data to and From the DialogFragment

In order to pass the data to the DialogFragment class, we can simply set the data using setArguments on the instance of the class. In order to return the data from the DialogFragments to the Activity/another fragment, we need to create our custom interface. In the following section, we’ll be creating an android application that does the following things:

  • Creates a Simple DialogFragment Dialog
  • A DialogFragment embedded in the Activity
  • DialogFragment with a style.
  • DialogFragment that returns data

Project Structure

android dialogfragment project

Code

The code for the activity_main.xml class is given below:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://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="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_above="@+id/btnDialogFragment"
        android:text="EMBED DIALOG FRAGMENT" />

    <Button
        android:id="@+id/btnDialogFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginTop="8dp"
        android:text="SIMPLE DIALOG FRAGMENT" />


    <Button
        android:id="@+id/btnDialogFragmentFullScreen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnDialogFragment"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:text="DIALOG FRAGMENT FULL SCREEN" />


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

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnAlertDialogFragment"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

Each of the Buttons would start a different type of DialogFragment. The xml layout for the custom view for a DialogFragment is defined in fragment_sample_dialog.xml file as shown below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://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="Please enter your username and password" />


    <EditText
        android:id="@+id/inEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Email Address"
        android:inputType="textEmailAddress" />

    <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>

So our Dialog would show a basic Login form. The code for the MainActivity.java is given below:

package com.journaldev.androiddialogfragment;


import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, MyDialogFragment.DialogListener {

    Button btnEmbedDialogFragment, btnDialogFragment, btnDialogFragmentFullScreen, btnAlertDialogFragment;
    TextView textView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        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
    public void onClick(View view) {

        switch (view.getId()) {
            case R.id.btnEmbedDialogFragment:
                MyDialogFragment dialogFragment = new MyDialogFragment();

                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

                ft.replace(R.id.frameLayout, dialogFragment);
                ft.commit();
                break;

            case R.id.btnDialogFragment:
                dialogFragment = new MyDialogFragment();

                Bundle bundle = new Bundle();
                bundle.putBoolean("notAlertDialog", true);

                dialogFragment.setArguments(bundle);

                ft = getSupportFragmentManager().beginTransaction();
                Fragment prev = getSupportFragmentManager().findFragmentByTag("dialog");
                if (prev != null) {
                    ft.remove(prev);
                }
                ft.addToBackStack(null);


                dialogFragment.show(ft, "dialog");
                break;

            case R.id.btnDialogFragmentFullScreen:
                dialogFragment = new MyDialogFragment();

                bundle = new Bundle();
                bundle.putString("email", "xyz@gmail.com");
                bundle.putBoolean("fullScreen", true);
                bundle.putBoolean("notAlertDialog", true);

                dialogFragment.setArguments(bundle);


                ft = getSupportFragmentManager().beginTransaction();
                prev = getSupportFragmentManager().findFragmentByTag("dialog");
                if (prev != null) {
                    ft.remove(prev);
                }
                ft.addToBackStack(null);


                dialogFragment.show(ft, "dialog");
                break;

            case R.id.btnAlertDialogFragment:
                dialogFragment = new MyDialogFragment();


                ft = getSupportFragmentManager().beginTransaction();
                prev = getSupportFragmentManager().findFragmentByTag("dialog");
                if (prev != null) {
                    ft.remove(prev);
                }
                ft.addToBackStack(null);


                dialogFragment.show(ft, "dialog");
                break;
        }
    }

    @Override
    public void onFinishEditDialog(String inputText) {

        if (TextUtils.isEmpty(inputText)) {
            textView.setText("Email was not entered");
        } else
            textView.setText("Email entered: " + inputText);
    }
}

The above class implements an interface MyDialogFragment.DialogListener which triggers the method onFinishEditDialog whenever the button of the DialogFragment is clicked. It displays the data entered in the Dialog on the Activity. The code for the MyDialogFragment.java class is given below:

package com.journaldev.androiddialogfragment;

import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

public class MyDialogFragment extends DialogFragment {

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {


        if (getArguments() != null) {
            if (getArguments().getBoolean("notAlertDialog")) {
                return super.onCreateDialog(savedInstanceState);
            }
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Alert Dialog");
        builder.setMessage("Alert Dialog inside DialogFragment");

        builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dismiss();
            }
        });

        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dismiss();
            }
        });

        return builder.create();

    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_sample_dialog, container, false);

    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);


        final EditText editText = view.findViewById(R.id.inEmail);

        if (getArguments() != null && !TextUtils.isEmpty(getArguments().getString("email")))
            editText.setText(getArguments().getString("email"));

        Button btnDone = view.findViewById(R.id.btnDone);
        btnDone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                DialogListener dialogListener = (DialogListener) getActivity();
                dialogListener.onFinishEditDialog(editText.getText().toString());
                dismiss();
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();

    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d("API123", "onCreate");

        boolean setFullScreen = false;
        if (getArguments() != null) {
            setFullScreen = getArguments().getBoolean("fullScreen");
        }

        if (setFullScreen)
            setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    public interface DialogListener {
        void onFinishEditDialog(String inputText);
    }


}

Inside onCreateDialog we create a normal AlertDialog. dismiss() function closes the Dialog. The output of the above application in action is given below: android dialogfragment output Notice that in the full screen Dialog, the data for the input field was already passed. That brings an end to this tutorial. You can download the project from the link below:

AndroidDialogFragment

Github Project Link

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Anupam Chugh

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more