1dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn/*
2dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * Copyright (C) 2010 The Android Open Source Project
3dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn *
4dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * you may not use this file except in compliance with the License.
6dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * You may obtain a copy of the License at
7dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn *
8dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn *
10dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * See the License for the specific language governing permissions and
14dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * limitations under the License.
15dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn */
16dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
17dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackbornpackage android.app;
18dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
197187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackbornimport android.content.Context;
20dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackbornimport android.content.DialogInterface;
21dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackbornimport android.os.Bundle;
22dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackbornimport android.view.LayoutInflater;
23dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackbornimport android.view.View;
24dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackbornimport android.view.ViewGroup;
25dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackbornimport android.view.Window;
26dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackbornimport android.view.WindowManager;
27dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
28bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackbornimport java.io.FileDescriptor;
29bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackbornimport java.io.PrintWriter;
30bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn
31dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn/**
32dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * A fragment that displays a dialog window, floating on top of its
33dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * activity's window.  This fragment contains a Dialog object, which it
34dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * displays as appropriate based on the fragment's state.  Control of
35dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * the dialog (deciding when to show, hide, dismiss it) should be done through
36dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * the API here, not with direct calls on the dialog.
37dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn *
38dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * <p>Implementations should override this class and implement
39dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} to supply the
40dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * content of the dialog.  Alternatively, they can override
41dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * {@link #onCreateDialog(Bundle)} to create an entirely custom dialog, such
42dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * as an AlertDialog, with its own content.
43727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
44727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>Topics covered here:
45727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <ol>
46727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <li><a href="#Lifecycle">Lifecycle</a>
47727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <li><a href="#BasicDialog">Basic Dialog</a>
48727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <li><a href="#AlertDialog">Alert Dialog</a>
49727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <li><a href="#DialogOrEmbed">Selecting Between Dialog or Embedding</a>
50727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * </ol>
51727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
52727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <a name="Lifecycle"></a>
53727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <h3>Lifecycle</h3>
54727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
55727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>DialogFragment does various things to keep the fragment's lifecycle
56727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * driving it, instead of the Dialog.  Note that dialogs are generally
57727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * autonomous entities -- they are their own window, receiving their own
58727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * input events, and often deciding on their own when to disappear (by
59727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * receiving a back key event or the user clicking on a button).
60727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
61727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>DialogFragment needs to ensure that what is happening with the Fragment
62727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * and Dialog states remains consistent.  To do this, it watches for dismiss
63fd516987de29a48425da5ee5aace5be40adcc674Scott Main * events from the dialog and takes care of removing its own state when they
64727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * happen.  This means you should use {@link #show(FragmentManager, String)}
65727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * or {@link #show(FragmentTransaction, String)} to add an instance of
66727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * DialogFragment to your UI, as these keep track of how DialogFragment should
67727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * remove itself when the dialog is dismissed.
68727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
69727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <a name="BasicDialog"></a>
70727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <h3>Basic Dialog</h3>
71727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
72727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>The simplest use of DialogFragment is as a floating container for the
73727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * fragment's view hierarchy.  A simple implementation may look like this:
74727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
75727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialog.java
76727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *      dialog}
77727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
78727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>An example showDialog() method on the Activity could be:
79727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
80727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialog.java
81727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *      add_dialog}
82727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
83727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>This removes any currently shown dialog, creates a new DialogFragment
84727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * with an argument, and shows it as a new state on the back stack.  When the
85727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * transaction is popped, the current DialogFragment and its Dialog will be
86727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * destroyed, and the previous one (if any) re-shown.  Note that in this case
87727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * DialogFragment will take care of popping the transaction of the Dialog
88727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * is dismissed separately from it.
89727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
90727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <a name="AlertDialog"></a>
91727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <h3>Alert Dialog</h3>
92727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
93727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>Instead of (or in addition to) implementing {@link #onCreateView} to
94727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * generate the view hierarchy inside of a dialog, you may implement
95727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * {@link #onCreateDialog(Bundle)} to create your own custom Dialog object.
96727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
97727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>This is most useful for creating an {@link AlertDialog}, allowing you
98727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * to display standard alerts to the user that are managed by a fragment.
99727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * A simple example implementation of this is:
100727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
101727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentAlertDialog.java
102727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *      dialog}
103727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
104727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>The activity creating this fragment may have the following methods to
105727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * show the dialog and receive results from it:
106727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
107727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentAlertDialog.java
108727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *      activity}
109727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
110727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>Note that in this case the fragment is not placed on the back stack, it
111727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * is just added as an indefinitely running fragment.  Because dialogs normally
112727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * are modal, this will still operate as a back stack, since the dialog will
113727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * capture user input until it is dismissed.  When it is dismissed, DialogFragment
114727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * will take care of removing itself from its fragment manager.
115727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
116727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <a name="DialogOrEmbed"></a>
117727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <h3>Selecting Between Dialog or Embedding</h3>
118727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
119727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>A DialogFragment can still optionally be used as a normal fragment, if
120727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * desired.  This is useful if you have a fragment that in some cases should
121727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * be shown as a dialog and others embedded in a larger UI.  This behavior
122727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * will normally be automatically selected for you based on how you are using
123727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * the fragment, but can be customized with {@link #setShowsDialog(boolean)}.
124727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
125727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>For example, here is a simple dialog fragment:
126727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
127727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialogOrActivity.java
128727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *      dialog}
129727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
130727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>An instance of this fragment can be created and shown as a dialog:
131727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
132727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialogOrActivity.java
133727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *      show_dialog}
134727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
135727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>It can also be added as content in a view hierarchy:
136727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *
137727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentDialogOrActivity.java
138727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn *      embed}
139dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn */
140dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackbornpublic class DialogFragment extends Fragment
141dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
142dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
143dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    /**
14472dc780f57b4396b808032d592c41d35644a3277Jean-Baptiste Queru     * Style for {@link #setStyle(int, int)}: a basic,
145dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * normal dialog.
146dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     */
147dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public static final int STYLE_NORMAL = 0;
148dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
149dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    /**
15072dc780f57b4396b808032d592c41d35644a3277Jean-Baptiste Queru     * Style for {@link #setStyle(int, int)}: don't include
151dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * a title area.
152dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     */
153dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public static final int STYLE_NO_TITLE = 1;
154dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
155dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    /**
15672dc780f57b4396b808032d592c41d35644a3277Jean-Baptiste Queru     * Style for {@link #setStyle(int, int)}: don't draw
157dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * any frame at all; the view hierarchy returned by {@link #onCreateView}
158dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * is entirely responsible for drawing the dialog.
159dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     */
160dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public static final int STYLE_NO_FRAME = 2;
161dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
162dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    /**
16372dc780f57b4396b808032d592c41d35644a3277Jean-Baptiste Queru     * Style for {@link #setStyle(int, int)}: like
164dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * {@link #STYLE_NO_FRAME}, but also disables all input to the dialog.
165dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * The user can not touch it, and its window will not receive input focus.
166dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     */
167dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public static final int STYLE_NO_INPUT = 3;
168dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
169dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    private static final String SAVED_DIALOG_STATE_TAG = "android:savedDialogState";
170dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    private static final String SAVED_STYLE = "android:style";
171dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    private static final String SAVED_THEME = "android:theme";
172dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    private static final String SAVED_CANCELABLE = "android:cancelable";
173727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    private static final String SAVED_SHOWS_DIALOG = "android:showsDialog";
174dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    private static final String SAVED_BACK_STACK_ID = "android:backStackId";
175dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
176dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    int mStyle = STYLE_NORMAL;
177dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    int mTheme = 0;
178dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    boolean mCancelable = true;
179727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    boolean mShowsDialog = true;
180dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    int mBackStackId = -1;
181dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
182dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    Dialog mDialog;
183bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    boolean mViewDestroyed;
184bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    boolean mDismissed;
185bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    boolean mShownByMe;
186dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
187dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public DialogFragment() {
188dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
189dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
190dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    /**
191b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn     * Call to customize the basic appearance and behavior of the
192dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * fragment's dialog.  This can be used for some common dialog behaviors,
193dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * taking care of selecting flags, theme, and other options for you.  The
194dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * same effect can be achieve by manually setting Dialog and Window
195b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn     * attributes yourself.  Calling this after the fragment's Dialog is
196b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn     * created will have no effect.
197dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     *
198dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * @param style Selects a standard style: may be {@link #STYLE_NORMAL},
199dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * {@link #STYLE_NO_TITLE}, {@link #STYLE_NO_FRAME}, or
200dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * {@link #STYLE_NO_INPUT}.
201dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * @param theme Optional custom theme.  If 0, an appropriate theme (based
202dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * on the style) will be selected for you.
203dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     */
204b7a2e4772220c4b41df1260cedaf8912f4b07547Dianne Hackborn    public void setStyle(int style, int theme) {
205dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        mStyle = style;
206dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (mStyle == STYLE_NO_FRAME || mStyle == STYLE_NO_INPUT) {
2076e90a362bc66cc67b1beae27b21d3f0148403b08Adam Powell            mTheme = com.android.internal.R.style.Theme_DeviceDefault_Dialog_NoFrame;
208dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
209dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (theme != 0) {
210dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            mTheme = theme;
211dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
212dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
213dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
214dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    /**
215727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * Display the dialog, adding the fragment to the given FragmentManager.  This
216dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * is a convenience for explicitly creating a transaction, adding the
217dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * fragment to it with the given tag, and committing it.  This does
218dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * <em>not</em> add the transaction to the back stack.  When the fragment
219dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * is dismissed, a new transaction will be executed to remove it from
220dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * the activity.
221727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * @param manager The FragmentManager this fragment will be added to.
222dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * @param tag The tag for this fragment, as per
223dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}.
224dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     */
225727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    public void show(FragmentManager manager, String tag) {
226bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        mDismissed = false;
227bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        mShownByMe = true;
22848e7b458694acdf3a4fc58e62437f1dbc4f29d83Dianne Hackborn        FragmentTransaction ft = manager.beginTransaction();
229dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        ft.add(this, tag);
230dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        ft.commit();
231dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
232dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
233063f850060bb28bc9984c352c0cbf8f13a00789dJeff Sharkey    /** {@hide} */
234063f850060bb28bc9984c352c0cbf8f13a00789dJeff Sharkey    public void showAllowingStateLoss(FragmentManager manager, String tag) {
235063f850060bb28bc9984c352c0cbf8f13a00789dJeff Sharkey        mDismissed = false;
236063f850060bb28bc9984c352c0cbf8f13a00789dJeff Sharkey        mShownByMe = true;
237063f850060bb28bc9984c352c0cbf8f13a00789dJeff Sharkey        FragmentTransaction ft = manager.beginTransaction();
238063f850060bb28bc9984c352c0cbf8f13a00789dJeff Sharkey        ft.add(this, tag);
239063f850060bb28bc9984c352c0cbf8f13a00789dJeff Sharkey        ft.commitAllowingStateLoss();
240063f850060bb28bc9984c352c0cbf8f13a00789dJeff Sharkey    }
241063f850060bb28bc9984c352c0cbf8f13a00789dJeff Sharkey
242dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    /**
243727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * Display the dialog, adding the fragment using an existing transaction
244727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * and then committing the transaction.
245dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * @param transaction An existing transaction in which to add the fragment.
246dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * @param tag The tag for this fragment, as per
247dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}.
248dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * @return Returns the identifier of the committed transaction, as per
249dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * {@link FragmentTransaction#commit() FragmentTransaction.commit()}.
250dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     */
251727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    public int show(FragmentTransaction transaction, String tag) {
252bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        mDismissed = false;
253bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        mShownByMe = true;
254dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        transaction.add(this, tag);
255bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        mViewDestroyed = false;
256dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        mBackStackId = transaction.commit();
257dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        return mBackStackId;
258dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
259dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
260dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    /**
261dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * Dismiss the fragment and its dialog.  If the fragment was added to the
262dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * back stack, all back stack state up to and including this entry will
263dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * be popped.  Otherwise, a new transaction will be committed to remove
264dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     * the fragment.
265dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     */
266dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void dismiss() {
267ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn        dismissInternal(false);
268ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn    }
269ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn
270cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn    /**
271cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn     * Version of {@link #dismiss()} that uses
272cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn     * {@link FragmentTransaction#commitAllowingStateLoss()
273cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn     * FragmentTransaction.commitAllowingStateLoss()}.  See linked
274cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn     * documentation for further details.
275cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn     */
276cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn    public void dismissAllowingStateLoss() {
277cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn        dismissInternal(true);
278cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn    }
279cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn
280ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn    void dismissInternal(boolean allowStateLoss) {
281bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        if (mDismissed) {
282bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            return;
283bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        }
284bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        mDismissed = true;
285bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        mShownByMe = false;
286dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (mDialog != null) {
287dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            mDialog.dismiss();
288def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn            mDialog = null;
289dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
290bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        mViewDestroyed = true;
291dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (mBackStackId >= 0) {
292def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn            getFragmentManager().popBackStack(mBackStackId,
293def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn                    FragmentManager.POP_BACK_STACK_INCLUSIVE);
294dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            mBackStackId = -1;
295dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        } else {
29648e7b458694acdf3a4fc58e62437f1dbc4f29d83Dianne Hackborn            FragmentTransaction ft = getFragmentManager().beginTransaction();
297dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            ft.remove(this);
2986908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn            if (allowStateLoss) {
2996908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn                ft.commitAllowingStateLoss();
3006908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn            } else {
3016908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn                ft.commit();
3026908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn            }
303dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
304dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
305ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn
306dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public Dialog getDialog() {
307dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        return mDialog;
308dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
309dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
310dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public int getTheme() {
311dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        return mTheme;
312dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
313dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
314727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    /**
315727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * Control whether the shown Dialog is cancelable.  Use this instead of
316727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * directly calling {@link Dialog#setCancelable(boolean)
317727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * Dialog.setCancelable(boolean)}, because DialogFragment needs to change
318727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * its behavior based on this.
319727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     *
320727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * @param cancelable If true, the dialog is cancelable.  The default
321727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * is true.
322727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     */
323dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void setCancelable(boolean cancelable) {
324dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        mCancelable = cancelable;
325dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (mDialog != null) mDialog.setCancelable(cancelable);
326dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
327dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
328727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    /**
329727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * Return the current value of {@link #setCancelable(boolean)}.
330727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     */
331327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn    public boolean isCancelable() {
332dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        return mCancelable;
333dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
334dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
335727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    /**
336727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * Controls whether this fragment should be shown in a dialog.  If not
337727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * set, no Dialog will be created in {@link #onActivityCreated(Bundle)},
338727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * and the fragment's view hierarchy will thus not be added to it.  This
339727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * allows you to instead use it as a normal fragment (embedded inside of
340727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * its activity).
341727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     *
342727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * <p>This is normally set for you based on whether the fragment is
343727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * associated with a container view ID passed to
344727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * {@link FragmentTransaction#add(int, Fragment) FragmentTransaction.add(int, Fragment)}.
345727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * If the fragment was added with a container, setShowsDialog will be
346727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * initialized to false; otherwise, it will be true.
347727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     *
348727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * @param showsDialog If true, the fragment will be displayed in a Dialog.
349727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * If false, no Dialog will be created and the fragment's view hierarchly
350727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * left undisturbed.
351727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     */
352727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    public void setShowsDialog(boolean showsDialog) {
353727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        mShowsDialog = showsDialog;
354727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    }
355727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn
356727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    /**
357727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     * Return the current value of {@link #setShowsDialog(boolean)}.
358727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn     */
359727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    public boolean getShowsDialog() {
360727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        return mShowsDialog;
361727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn    }
362727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn
363dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    @Override
36431479e33e6692444604219534d06009cdb7e7c33Adam Powell    public void onAttach(Context context) {
36531479e33e6692444604219534d06009cdb7e7c33Adam Powell        super.onAttach(context);
366bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        if (!mShownByMe) {
367bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            // If not explicitly shown through our API, take this as an
368bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            // indication that the dialog is no longer dismissed.
369bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            mDismissed = false;
370bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        }
371bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    }
372bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn
373bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    @Override
374bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    public void onDetach() {
375bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        super.onDetach();
376bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        if (!mShownByMe && !mDismissed) {
377bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            // The fragment was not shown by a direct call here, it is not
378bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            // dismissed, and now it is being detached...  well, okay, thou
379bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            // art now dismissed.  Have fun.
380bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            mDismissed = true;
381bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        }
382bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    }
383bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn
384bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    @Override
385dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void onCreate(Bundle savedInstanceState) {
386dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        super.onCreate(savedInstanceState);
387727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn
388727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        mShowsDialog = mContainerId == 0;
389727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn
390dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (savedInstanceState != null) {
391727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            mStyle = savedInstanceState.getInt(SAVED_STYLE, STYLE_NORMAL);
392727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            mTheme = savedInstanceState.getInt(SAVED_THEME, 0);
393727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            mCancelable = savedInstanceState.getBoolean(SAVED_CANCELABLE, true);
394727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            mShowsDialog = savedInstanceState.getBoolean(SAVED_SHOWS_DIALOG, mShowsDialog);
395727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            mBackStackId = savedInstanceState.getInt(SAVED_BACK_STACK_ID, -1);
396dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
397dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
398dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
3997187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn    /** @hide */
4007187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn    @Override
401c7146beabe21c84248c2c62336b0af8c2f19f4f5George Mount    public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
4027187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn        if (!mShowsDialog) {
403c7146beabe21c84248c2c62336b0af8c2f19f4f5George Mount            return super.onGetLayoutInflater(savedInstanceState);
4047187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn        }
4057187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn
4067187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn        mDialog = onCreateDialog(savedInstanceState);
4077187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn        switch (mStyle) {
4087187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn            case STYLE_NO_INPUT:
4097187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn                mDialog.getWindow().addFlags(
4107187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
4117187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn                        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
4127187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn                // fall through...
4137187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn            case STYLE_NO_FRAME:
4147187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn            case STYLE_NO_TITLE:
4157187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn                mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
4167187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn        }
41725193d330e7daaed1d4678609326c4f84bf3d584Dianne Hackborn        if (mDialog != null) {
41825193d330e7daaed1d4678609326c4f84bf3d584Dianne Hackborn            return (LayoutInflater)mDialog.getContext().getSystemService(
41925193d330e7daaed1d4678609326c4f84bf3d584Dianne Hackborn                    Context.LAYOUT_INFLATER_SERVICE);
42025193d330e7daaed1d4678609326c4f84bf3d584Dianne Hackborn        }
421a5fc6f006f67867417b7a427de6e7394c4312decTodd Kennedy        return (LayoutInflater) mHost.getContext().getSystemService(
4227187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn                Context.LAYOUT_INFLATER_SERVICE);
4237187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn    }
4247187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn
4257187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn    /**
4267187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * Override to build your own custom Dialog container.  This is typically
4277187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * used to show an AlertDialog instead of a generic Dialog; when doing so,
4287187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} does not need
4297187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * to be implemented since the AlertDialog takes care of its own content.
4307187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     *
4317187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * <p>This method will be called after {@link #onCreate(Bundle)} and
4327187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * before {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.  The
4337187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * default implementation simply instantiates and returns a {@link Dialog}
4347187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * class.
4357187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     *
436f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn     * <p><em>Note: DialogFragment own the {@link Dialog#setOnCancelListener
437f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn     * Dialog.setOnCancelListener} and {@link Dialog#setOnDismissListener
438f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn     * Dialog.setOnDismissListener} callbacks.  You must not set them yourself.</em>
439f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn     * To find out about these events, override {@link #onCancel(DialogInterface)}
440f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn     * and {@link #onDismiss(DialogInterface)}.</p>
441f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn     *
4427187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * @param savedInstanceState The last saved instance state of the Fragment,
4437187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * or null if this is a freshly created Fragment.
4447187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     *
4457187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     * @return Return a new Dialog instance to be displayed by the Fragment.
4467187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn     */
447dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public Dialog onCreateDialog(Bundle savedInstanceState) {
448dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        return new Dialog(getActivity(), getTheme());
449dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
450dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
451dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void onCancel(DialogInterface dialog) {
452dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
453dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
454dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void onDismiss(DialogInterface dialog) {
455bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        if (!mViewDestroyed) {
456ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn            // Note: we need to use allowStateLoss, because the dialog
457ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn            // dispatches this asynchronously so we can receive the call
458ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn            // after the activity is paused.  Worst case, when the user comes
459ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn            // back to the activity they see the dialog again.
460ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn            dismissInternal(true);
461def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn        }
462dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
463dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
464dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    @Override
465dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void onActivityCreated(Bundle savedInstanceState) {
466dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        super.onActivityCreated(savedInstanceState);
467727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn
468727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        if (!mShowsDialog) {
469727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            return;
470727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        }
471727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn
472dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        View view = getView();
473dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (view != null) {
474dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            if (view.getParent() != null) {
47531479e33e6692444604219534d06009cdb7e7c33Adam Powell                throw new IllegalStateException(
47631479e33e6692444604219534d06009cdb7e7c33Adam Powell                        "DialogFragment can not be attached to a container view");
477dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            }
478dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            mDialog.setContentView(view);
479dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
48031479e33e6692444604219534d06009cdb7e7c33Adam Powell        final Activity activity = getActivity();
48131479e33e6692444604219534d06009cdb7e7c33Adam Powell        if (activity != null) {
48231479e33e6692444604219534d06009cdb7e7c33Adam Powell            mDialog.setOwnerActivity(activity);
48331479e33e6692444604219534d06009cdb7e7c33Adam Powell        }
484dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        mDialog.setCancelable(mCancelable);
485f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn        if (!mDialog.takeCancelAndDismissListeners("DialogFragment", this, this)) {
486f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn            throw new IllegalStateException(
487f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn                    "You can not set Dialog's OnCancelListener or OnDismissListener");
488f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn        }
489dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (savedInstanceState != null) {
490dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG);
491dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            if (dialogState != null) {
492dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn                mDialog.onRestoreInstanceState(dialogState);
493dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            }
494dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
495dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
496dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
497dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    @Override
498dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void onStart() {
499dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        super.onStart();
500def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn        if (mDialog != null) {
501bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            mViewDestroyed = false;
502def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn            mDialog.show();
503def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn        }
504dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
505dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
506dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    @Override
507dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void onSaveInstanceState(Bundle outState) {
508dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        super.onSaveInstanceState(outState);
509dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        if (mDialog != null) {
510dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            Bundle dialogState = mDialog.onSaveInstanceState();
511dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            if (dialogState != null) {
512dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn                outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState);
513dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn            }
514dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        }
515727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        if (mStyle != STYLE_NORMAL) {
516727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            outState.putInt(SAVED_STYLE, mStyle);
517727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        }
518727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        if (mTheme != 0) {
519727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            outState.putInt(SAVED_THEME, mTheme);
520727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        }
521727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        if (!mCancelable) {
522727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            outState.putBoolean(SAVED_CANCELABLE, mCancelable);
523727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        }
524727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        if (!mShowsDialog) {
525727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            outState.putBoolean(SAVED_SHOWS_DIALOG, mShowsDialog);
526727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        }
527727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        if (mBackStackId != -1) {
528727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn            outState.putInt(SAVED_BACK_STACK_ID, mBackStackId);
529727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn        }
530dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
531dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
532dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    @Override
533dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void onStop() {
534dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        super.onStop();
535def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn        if (mDialog != null) {
536def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn            mDialog.hide();
537def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn        }
538dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
539dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn
540dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    /**
541def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn     * Remove dialog.
542dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn     */
543dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    @Override
544dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    public void onDestroyView() {
545dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn        super.onDestroyView();
546def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn        if (mDialog != null) {
547def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn            // Set removed here because this dismissal is just to hide
548def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn            // the dialog -- we don't want this to cause the fragment to
549def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn            // actually be removed.
550bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn            mViewDestroyed = true;
551def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn            mDialog.dismiss();
552def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn            mDialog = null;
553def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn        }
554dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn    }
555bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn
556bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    @Override
557bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
558bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        super.dump(prefix, fd, writer, args);
559bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        writer.print(prefix); writer.println("DialogFragment:");
560bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        writer.print(prefix); writer.print("  mStyle="); writer.print(mStyle);
561bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn                writer.print(" mTheme=0x"); writer.println(Integer.toHexString(mTheme));
562bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        writer.print(prefix); writer.print("  mCancelable="); writer.print(mCancelable);
563bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn                writer.print(" mShowsDialog="); writer.print(mShowsDialog);
564bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn                writer.print(" mBackStackId="); writer.println(mBackStackId);
565bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        writer.print(prefix); writer.print("  mDialog="); writer.println(mDialog);
566bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn        writer.print(prefix); writer.print("  mViewDestroyed="); writer.print(mViewDestroyed);
567bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn                writer.print(" mDismissed="); writer.print(mDismissed);
568bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn                writer.print(" mShownByMe="); writer.println(mShownByMe);
569bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn    }
570dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn}
571