DialogFragment

satya - Thursday, February 17, 2011 8:57:53 AM

You will see the API here

You will see the API here

In the preview release it is only on your local drive.

satya - Thursday, February 17, 2011 9:00:42 AM

A dialogfragment seem to work in multiple modes....

In one mode looks like you can just supply a view and the dialog fragment will then frame that view and display it as a view. In this mode programmer is in charge of putting the buttons necessary to dismiss the dialog etc. It is also clear in this mode how one would set the title.

in the other mode a prorgramer can return a whole dialog interface created by an alert dialog builder.

It is not clear how these two ideas in dialog fragments intermingle.

satya - Thursday, February 17, 2011 9:03:20 AM

A dialogfragment seem to remove itself if dismissed

looks like a dialog fragment monitors its dismiss and remove itself as a fragment using the fragment manager.

satya - Thursday, February 17, 2011 9:10:44 AM

A simple dialog that uses a view


public class GenericPromptDialogFragment 
extends MonitorDialogFragment 
{
    @Override    
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        this.setCancelable(true);
        int style = DialogFragment.STYLE_NORMAL, theme = 0;
        setStyle(style,theme);
    }
    
    public View onCreateView(LayoutInflater inflater,            
            ViewGroup container, 
            Bundle savedInstanceState)

    {
        View v = inflater.inflate(R.layout.dialog,container,false);
        return v;
    }
}

satya - Thursday, February 17, 2011 9:12:20 AM

Here is a simple dialog layout


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:padding="4dip"
    android:gravity="center_horizontal"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_gravity="center_vertical|center_horizontal"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:gravity="top|center_horizontal" />

   <Button android:id="@+id/show"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_weight="0"
        android:text="@string/show">
        <requestFocus />
    </Button>

</LinearLayout>

satya - Thursday, February 17, 2011 9:13:32 AM

The order of onCreateDialog and onCreateView

onCreateDialog is called before onCreateView

satya - Thursday, February 17, 2011 9:30:07 AM

The other order of events in one dialogfragment


onCreate
onActivityCreated
onCreateDialog
onCreateView
onStart

onCancel
onDismissDialog
onStop
onDismissView

satya - Thursday, February 17, 2011 9:35:37 AM

The nature of dialog fragment dismiss

Dismiss the fragment and its dialog. If the fragment was added to the back stack, all back stack state up to and including this entry will be popped. Otherwise, a new transaction will be committed to remove the fragment.

In layman terms, when a dismiss is called, it will go back to the previous view as dictated by what is its back. This happens if the dialog fragment is enabled for back stack by adding to the backstack.

otherwise the dialog fragment is removed from the fragment manager.

satya - Thursday, February 17, 2011 9:37:54 AM

is dialogfragment remove the same as dismiss?

is dialogfragment remove the same as dismiss?

Search for: is dialogfragment remove the same as dismiss?

At least the remove seem to invoke ondismiss

satya - Thursday, February 17, 2011 10:38:04 AM

Dismissing a dialog through fragment remove


FragmentManager fm = this.getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.remove(this);
ft.commit();

satya - Thursday, February 17, 2011 10:41:08 AM

order of events for the above


onStop
onDestroyView
onDismissDialog

This semantics differ from hitting the back button when the dialog is available.

satya - Thursday, February 17, 2011 10:47:28 AM

Flow of dismiss


onDismiss
onStop
onDestroyView

This is in line with back

satya - Thursday, February 17, 2011 11:20:44 AM

Behavior of show(fragmenttransaction, tag)

Display the dialog, adding the fragment to the given FragmentManager. This is a convenience for explicitly creating a transaction, adding the fragment to it with the given tag, and committing it.

This does not add the transaction to the back stack.

When the fragment is dismissed, a new transaction will be executed to remove it from the activity.

satya - Monday, February 21, 2011 7:51:49 PM

Nature of dismiss

A dismiss will automatically remove the dialog fragment from the fragment manager. This means you cannot really hold on to this pointer to the dialog fragment outside of the life cycle of the dialog.

satya - Monday, February 21, 2011 7:52:59 PM

onDismissDialog is called when the device rotates....

Keep in mind that onDismissDialog can not only be called when we call "dismiss" explicitly but also automatically when you rotate the device.

satya - Wed Oct 31 2012 10:34:34 GMT-0400 (Eastern Daylight Time)

Here is an approach to callbacks for dialog fragments


public class DatePickerFragment extends DialogFragment
   implements DatePickerDialog.OnDateSetListener 
{
   public static String tag = "DatePickerFragment";
   private DurationControl parent;
   
   public DatePickerFragment(DurationControl inParent)
   {
      parent = inParent;
      Bundle argsBundle = this.getArguments();
      if (argsBundle == null)
      {
         argsBundle = new Bundle();
      }
      argsBundle.putInt("parentid", inParent.getId());
      this.setArguments(argsBundle);
   }
   
   //Default constructor
   public DatePickerFragment()
   {
      Log.d(tag,"constructed");
   }
   @Override
   public Dialog onCreateDialog(Bundle savedInstanceState) 
   {
      //this.establishParent();
      // Use the current date as the default date in the picker
      final Calendar c = Calendar.getInstance();
      int year = c.get(Calendar.YEAR);
      int month = c.get(Calendar.MONTH);
      int day = c.get(Calendar.DAY_OF_MONTH);
      
      // Create a new instance of DatePickerDialog and return it
      return new DatePickerDialog(getActivity(), this, year, month, day);
   }
   
   public void onDateSet(DatePicker view, int year, int month, int day) {
   // Do something with the date chosen by the user
      parent.reportTransient(tag, "date clicked");
   }
   
   @Override
   public void onActivityCreated(Bundle savedInstanceState) {
      // TODO Auto-generated method stub
      super.onActivityCreated(savedInstanceState);
      Log.d(tag,"DatePickerFragment onActivity created called");
      this.establishParent();
   }
   
   private void establishParent()
   {
      if (parent != null) return;
      Log.d(tag, "establishing parent");
      int parentid = this.getArguments().getInt("parentid");
      View x = this.getActivity().findViewById(parentid);
      if (x == null)
      {
         throw new RuntimeException("Sorry not able to establish parent on restart");
      }
      parent = (DurationControl)x;
   }
}

Notice how the constructor is used to get the id of the view and save it in the argument bundle. This id is retrieved and the view relocated to set the local pointer of the this dialog.

onActivityCreated appears a reasonable place as the views would have been available by that time.

satya - Wed Oct 31 2012 10:37:59 GMT-0400 (Eastern Daylight Time)

Here is how I would have invoked this dialog from a compound control view


public void onClick(View v)
   {
      Button b = (Button)v;
      if (b.getId() == R.id.fromButton)
      {
          DialogFragment newFragment = new DatePickerFragment(this);
           newFragment.show(getFragmentManager(), "com.androidbook.tags.datepicker");       
      } 
   }//eof-onclick