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.
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?
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:
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:
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: 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:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
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.