Android Adventures - Dialog Classes In DialogFragments
Written by Mike James   
Thursday, 31 July 2014
Article Index
Android Adventures - Dialog Classes In DialogFragments
Communicating with the Activity
Date and Time Picker Dialogs

The relationship between a DialogFragment and the Dialog within can seem mysterious, but in the previous chapter we discovered how to make a custom dialog using nothing but DialogFragment. Now we have to find out how we can use the Dialog class to do the same thing.

 

Android Adventures - Mastering Fragments & Dialogs

coverfrag

Contents

This book is currently being revised. Chapter 5 and later refer to an earlier version of Android Studio - revisit for updates.

  1. Introducing Fragments
  2. Fragments and Android Studio XML
  3. Static Fragments
  4. Dynamic Fragments (Coming soon)

  5. Fragment And Activity Working Together
  6. Managing Fragments
  7. Custom dialogs using DialogFragment
  8. Dialog Classes In DialogFragment
  9. A NumberPicker DialogFragment Project
  10. ViewPager

If you are interested in creating custom template also see:

Custom Projects In Android Studio

Androidgears

 

I think if Android was being designed from scratch we probably wouldn't have the Dialog class in its current form. A DialogFragment does most of what you want and could easily be extended to provide the facilities of, say, DialogAlert. 

However, systems like Android tend to grow and evolve and we have the Dialog class and the DialogFragment class, which can do most of the same work. 

How Dialog and AlertDialog work

Before the Fragment was introduced the Dialog class was all you used. To create a dialog you simply created an instance of the Dialog class and call its show method to make the dialog window appear. 

In most cases you don't really want a raw dialog as generated by the Dialog class. You want a standard dialog with buttons and so on - you want an AlertDialog.

An AlertDialog is a subclass of Dialog and it comes with a range of standard dialog widgets that you can create using just code. You can use AlertDialog to show dialogs with up to three buttons, a title and some text and a list of choices. You can also set a completely custom layout and mix in the standard widgets as you choose. 

To create the AlertDialog customized with just the widgets you want you have to use the AlertDialog.Builder object. This has a range of methods that are used to setup the AlertDialog and then finally to create it.

This is an example of the builder pattern and it is very commonly used in Java. Instead of creating a complex set of constructors for an object that has lots of possible initializations you create an associated builder object which has methods for the different initializations. The builder creates the object when it has been fully configured.

So to create an AlertDialog with two buttons, an Ok and Cancel button we need to write code that first creates the builder:

AlertDialog.Builder myBuilder=
      new AlertDialog.Builder(getActivity());

You have to specify the Activity that the dialog is going to be used with. Now we can use myBuilder to initialize the AlertDialog we want to create. For example to give it a title:

myBuilder.setTitle("My Alert Dialog");

We can add an Ok and Cancel button using:

myBuilder.setPositiveButton("Ok",myDialogEvent);
myBuilder.setNegativeButton("Cancel",myDialogEvent);

Finally we can create the AlertDialog object:

AlertDialog myAlert=myBuilder.create();

The only thing we need to clarify is the nature of the myDialogEvent object. This is an object of type DialogInterface.OnClickListener which has a single onClick(DialogInterface,whichButton) method. As you can guess the event parameters tell you which dialog has fired the event and which button. 

The OnClickListener can be created in many different ways but an annoymouse class is the simplest way:

DialogInterface.OnClickListener myDialogEvent =
          new DialogInterface.OnClickListener(){
 @Override
 public void onClick(
         DialogInterface dialog, int which) {
  //do something
 }
};

 

Of course in a real program the onClick method would actually do something and would almost certainly test the which parameter to find out which button the user had clicked - the positive button is -1, negative is -2 and so on. There are also constants BUTTON_POSITIVE and BUTTON_NEGATIVE which you should use rather than the actual integer values which could change. An alternative method is to define a different OnClickListener for each of the buttons - what is best depends on what you are doing.

Putting all of the code together gives:

DialogInterface.OnClickListener myDialogEvent =
       new DialogInterface.OnClickListener(){
@Override
 public void onClick(
          DialogInterface dialog, int which) {
   //do something
 }
};

AlertDialog.Builder myBuilder=new
             AlertDialog.Builder(getActivity());
myBuilder.setTitle("My Alert Dialog");
myBuilder.setPositiveButton("Ok",myDialogEvent);
myBuilder.setNegativeButton("Cancel",myDialogEvent);
AlertDialog myAlert=myBuilder.create();

Fluent Style

This code, given above, works and it shows you the logic of creating an AlertDialog but it isn't the way most programmers would write it. Most builder objects are set up so that most of their methods return the same builder object. This allows the calls to be chained together to give a fluent style.  

Also most programmers would define the Listener object within the button creation calls. 

Putting all this together gives the more usual form of the code:

AlertDialog myAlert=
         new AlertDialog.Builder(getActivity())
  .setTitle("My Alert Dialog")
  .setPositiveButton("Ok",
      new DialogInterface.OnClickListener(){
       @Override
       public void onClick(
          DialogInterface dialog, int which) {
        //do something as Ok button clicked
       }
      })
  .setNegativeButton("Cancel",
      new DialogInterface.OnClickListener(){
       @Override
       public void onClick(
          DialogInterface dialog, int which) {
        //do something as Cancel button clicked
       }
      })
   .create();

 

You should have no trouble seeing that two are equivalent apart from using two separate OnClickListener objects.

Putting the Alert into a DialogFragment

Before the DialogFragment we would have simply called the AlertDialog or any Dialog's show method to display the dialog on the screen. 

Now this is not the way to do things.

Do not call the any dialog's show method directly. 

All dialogs should be contained within a DialogFragment and you should call its show method to display the dialog and add the DialogFragment to the FragmentManager. 

Let's see how this works.

If you remember the description of how the DialogFragment works you will recall that onCreateView is called so that the DialogFragment can create its UI - just like any Fragment. The big difference is that in this case the onCreateView method creates its UI not in the Activity's window but in a window belonging to the Dialog created by the onCreateDialog method. The onCreateDialog method is called automatically when the DialogFramgment needs to create the Dialog it contains and uses to draw its UI. 

However, there is an alternative way to create the UI.

The Dialog created in onCreateDialog can create the UI and we can ignore the onCreateView method entirely. The DialogFragment doesn't really care how the UI is created - by the Dialog it contains or by itself. 

So what we need to do is override the onCreateDialog method in a suitable DialogFragment so that it returns an AlertDialog set up to show whatever UI we want to show. 

 

Androidgears

 

 



Last Updated ( Saturday, 25 July 2015 )