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 233dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn /** 234727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * Display the dialog, adding the fragment using an existing transaction 235727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * and then committing the transaction. 236dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * @param transaction An existing transaction in which to add the fragment. 237dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * @param tag The tag for this fragment, as per 238dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * {@link FragmentTransaction#add(Fragment, String) FragmentTransaction.add}. 239dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * @return Returns the identifier of the committed transaction, as per 240dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * {@link FragmentTransaction#commit() FragmentTransaction.commit()}. 241dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn */ 242727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn public int show(FragmentTransaction transaction, String tag) { 243bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mDismissed = false; 244bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mShownByMe = true; 245dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn transaction.add(this, tag); 246bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mViewDestroyed = false; 247dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn mBackStackId = transaction.commit(); 248dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn return mBackStackId; 249dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 250dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 251dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn /** 252dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * Dismiss the fragment and its dialog. If the fragment was added to the 253dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * back stack, all back stack state up to and including this entry will 254dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * be popped. Otherwise, a new transaction will be committed to remove 255dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn * the fragment. 256dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn */ 257dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void dismiss() { 258ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn dismissInternal(false); 259ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn } 260ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn 261cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn /** 262cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn * Version of {@link #dismiss()} that uses 263cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn * {@link FragmentTransaction#commitAllowingStateLoss() 264cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn * FragmentTransaction.commitAllowingStateLoss()}. See linked 265cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn * documentation for further details. 266cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn */ 267cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn public void dismissAllowingStateLoss() { 268cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn dismissInternal(true); 269cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn } 270cf407ad88bef3bc640489b300f23eaa8ea0b724eDianne Hackborn 271ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn void dismissInternal(boolean allowStateLoss) { 272bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn if (mDismissed) { 273bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn return; 274bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn } 275bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mDismissed = true; 276bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mShownByMe = false; 277dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (mDialog != null) { 278dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn mDialog.dismiss(); 279def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn mDialog = null; 280dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 281bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mViewDestroyed = true; 282dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (mBackStackId >= 0) { 283def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn getFragmentManager().popBackStack(mBackStackId, 284def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn FragmentManager.POP_BACK_STACK_INCLUSIVE); 285dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn mBackStackId = -1; 286dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } else { 28748e7b458694acdf3a4fc58e62437f1dbc4f29d83Dianne Hackborn FragmentTransaction ft = getFragmentManager().beginTransaction(); 288dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn ft.remove(this); 2896908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn if (allowStateLoss) { 2906908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn ft.commitAllowingStateLoss(); 2916908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn } else { 2926908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn ft.commit(); 2936908cd154c5a2ed2e3b21d40f51952d45be69184Dianne Hackborn } 294dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 295dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 296ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn 297dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public Dialog getDialog() { 298dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn return mDialog; 299dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 300dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 301dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public int getTheme() { 302dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn return mTheme; 303dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 304dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 305727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn /** 306727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * Control whether the shown Dialog is cancelable. Use this instead of 307727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * directly calling {@link Dialog#setCancelable(boolean) 308727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * Dialog.setCancelable(boolean)}, because DialogFragment needs to change 309727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * its behavior based on this. 310727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * 311727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * @param cancelable If true, the dialog is cancelable. The default 312727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * is true. 313727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn */ 314dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void setCancelable(boolean cancelable) { 315dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn mCancelable = cancelable; 316dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (mDialog != null) mDialog.setCancelable(cancelable); 317dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 318dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 319727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn /** 320727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * Return the current value of {@link #setCancelable(boolean)}. 321727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn */ 322327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn public boolean isCancelable() { 323dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn return mCancelable; 324dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 325dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 326727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn /** 327727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * Controls whether this fragment should be shown in a dialog. If not 328727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * set, no Dialog will be created in {@link #onActivityCreated(Bundle)}, 329727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * and the fragment's view hierarchy will thus not be added to it. This 330727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * allows you to instead use it as a normal fragment (embedded inside of 331727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * its activity). 332727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * 333727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * <p>This is normally set for you based on whether the fragment is 334727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * associated with a container view ID passed to 335727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * {@link FragmentTransaction#add(int, Fragment) FragmentTransaction.add(int, Fragment)}. 336727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * If the fragment was added with a container, setShowsDialog will be 337727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * initialized to false; otherwise, it will be true. 338727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * 339727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * @param showsDialog If true, the fragment will be displayed in a Dialog. 340727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * If false, no Dialog will be created and the fragment's view hierarchly 341727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * left undisturbed. 342727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn */ 343727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn public void setShowsDialog(boolean showsDialog) { 344727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn mShowsDialog = showsDialog; 345727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn } 346727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn 347727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn /** 348727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn * Return the current value of {@link #setShowsDialog(boolean)}. 349727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn */ 350727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn public boolean getShowsDialog() { 351727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn return mShowsDialog; 352727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn } 353727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn 354dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn @Override 355bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn public void onAttach(Activity activity) { 356bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn super.onAttach(activity); 357bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn if (!mShownByMe) { 358bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn // If not explicitly shown through our API, take this as an 359bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn // indication that the dialog is no longer dismissed. 360bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mDismissed = false; 361bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn } 362bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn } 363bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn 364bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn @Override 365bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn public void onDetach() { 366bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn super.onDetach(); 367bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn if (!mShownByMe && !mDismissed) { 368bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn // The fragment was not shown by a direct call here, it is not 369bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn // dismissed, and now it is being detached... well, okay, thou 370bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn // art now dismissed. Have fun. 371bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mDismissed = true; 372bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn } 373bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn } 374bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn 375bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn @Override 376dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void onCreate(Bundle savedInstanceState) { 377dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn super.onCreate(savedInstanceState); 378727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn 379727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn mShowsDialog = mContainerId == 0; 380727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn 381dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (savedInstanceState != null) { 382727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn mStyle = savedInstanceState.getInt(SAVED_STYLE, STYLE_NORMAL); 383727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn mTheme = savedInstanceState.getInt(SAVED_THEME, 0); 384727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn mCancelable = savedInstanceState.getBoolean(SAVED_CANCELABLE, true); 385727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn mShowsDialog = savedInstanceState.getBoolean(SAVED_SHOWS_DIALOG, mShowsDialog); 386727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn mBackStackId = savedInstanceState.getInt(SAVED_BACK_STACK_ID, -1); 387dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 3887187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn 389dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 390dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 3917187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn /** @hide */ 3927187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn @Override 3937187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn public LayoutInflater getLayoutInflater(Bundle savedInstanceState) { 3947187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn if (!mShowsDialog) { 3957187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn return super.getLayoutInflater(savedInstanceState); 3967187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn } 3977187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn 3987187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn mDialog = onCreateDialog(savedInstanceState); 3997187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn switch (mStyle) { 4007187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn case STYLE_NO_INPUT: 4017187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn mDialog.getWindow().addFlags( 4027187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | 4037187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 4047187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn // fall through... 4057187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn case STYLE_NO_FRAME: 4067187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn case STYLE_NO_TITLE: 4077187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 4087187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn } 40925193d330e7daaed1d4678609326c4f84bf3d584Dianne Hackborn if (mDialog != null) { 41025193d330e7daaed1d4678609326c4f84bf3d584Dianne Hackborn return (LayoutInflater)mDialog.getContext().getSystemService( 41125193d330e7daaed1d4678609326c4f84bf3d584Dianne Hackborn Context.LAYOUT_INFLATER_SERVICE); 41225193d330e7daaed1d4678609326c4f84bf3d584Dianne Hackborn } 41325193d330e7daaed1d4678609326c4f84bf3d584Dianne Hackborn return (LayoutInflater)mActivity.getSystemService( 4147187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn Context.LAYOUT_INFLATER_SERVICE); 4157187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn } 4167187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn 4177187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn /** 4187187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * Override to build your own custom Dialog container. This is typically 4197187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * used to show an AlertDialog instead of a generic Dialog; when doing so, 4207187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} does not need 4217187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * to be implemented since the AlertDialog takes care of its own content. 4227187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * 4237187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * <p>This method will be called after {@link #onCreate(Bundle)} and 4247187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * before {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}. The 4257187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * default implementation simply instantiates and returns a {@link Dialog} 4267187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * class. 4277187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * 428f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn * <p><em>Note: DialogFragment own the {@link Dialog#setOnCancelListener 429f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn * Dialog.setOnCancelListener} and {@link Dialog#setOnDismissListener 430f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn * Dialog.setOnDismissListener} callbacks. You must not set them yourself.</em> 431f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn * To find out about these events, override {@link #onCancel(DialogInterface)} 432f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn * and {@link #onDismiss(DialogInterface)}.</p> 433f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn * 4347187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * @param savedInstanceState The last saved instance state of the Fragment, 4357187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * or null if this is a freshly created Fragment. 4367187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * 4377187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn * @return Return a new Dialog instance to be displayed by the Fragment. 4387187ccb93ee8adbb745fcbb901cfacfeed397a23Dianne Hackborn */ 439dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public Dialog onCreateDialog(Bundle savedInstanceState) { 440dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn return new Dialog(getActivity(), getTheme()); 441dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 442dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 443dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void onCancel(DialogInterface dialog) { 444dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 445dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 446dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void onDismiss(DialogInterface dialog) { 447bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn if (!mViewDestroyed) { 448ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn // Note: we need to use allowStateLoss, because the dialog 449ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn // dispatches this asynchronously so we can receive the call 450ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn // after the activity is paused. Worst case, when the user comes 451ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn // back to the activity they see the dialog again. 452ab36acb39941ce981dddda9f9cf4d2d23a56fd26Dianne Hackborn dismissInternal(true); 453def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn } 454dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 455dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 456dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn @Override 457dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void onActivityCreated(Bundle savedInstanceState) { 458dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn super.onActivityCreated(savedInstanceState); 459727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn 460727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn if (!mShowsDialog) { 461727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn return; 462727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn } 463727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn 464dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn View view = getView(); 465dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (view != null) { 466dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (view.getParent() != null) { 467dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn throw new IllegalStateException("DialogFragment can not be attached to a container view"); 468dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 469dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn mDialog.setContentView(view); 470dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 471dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn mDialog.setOwnerActivity(getActivity()); 472dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn mDialog.setCancelable(mCancelable); 473f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn if (!mDialog.takeCancelAndDismissListeners("DialogFragment", this, this)) { 474f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn throw new IllegalStateException( 475f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn "You can not set Dialog's OnCancelListener or OnDismissListener"); 476f812fee071b9992872009b2dcd7969c7ce882a90Dianne Hackborn } 477dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (savedInstanceState != null) { 478dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG); 479dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (dialogState != null) { 480dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn mDialog.onRestoreInstanceState(dialogState); 481dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 482dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 483dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 484dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 485dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn @Override 486dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void onStart() { 487dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn super.onStart(); 488def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn if (mDialog != null) { 489bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mViewDestroyed = false; 490def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn mDialog.show(); 491def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn } 492dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 493dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 494dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn @Override 495dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void onSaveInstanceState(Bundle outState) { 496dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn super.onSaveInstanceState(outState); 497dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (mDialog != null) { 498dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn Bundle dialogState = mDialog.onSaveInstanceState(); 499dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn if (dialogState != null) { 500dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState); 501dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 502dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 503727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn if (mStyle != STYLE_NORMAL) { 504727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn outState.putInt(SAVED_STYLE, mStyle); 505727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn } 506727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn if (mTheme != 0) { 507727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn outState.putInt(SAVED_THEME, mTheme); 508727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn } 509727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn if (!mCancelable) { 510727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn outState.putBoolean(SAVED_CANCELABLE, mCancelable); 511727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn } 512727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn if (!mShowsDialog) { 513727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn outState.putBoolean(SAVED_SHOWS_DIALOG, mShowsDialog); 514727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn } 515727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn if (mBackStackId != -1) { 516727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn outState.putInt(SAVED_BACK_STACK_ID, mBackStackId); 517727782053ced0cac5beadc2c7ee9382d0f1ba1f5Dianne Hackborn } 518dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 519dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 520dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn @Override 521dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void onStop() { 522dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn super.onStop(); 523def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn if (mDialog != null) { 524def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn mDialog.hide(); 525def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn } 526dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 527dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn 528dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn /** 529def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn * Remove dialog. 530dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn */ 531dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn @Override 532dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn public void onDestroyView() { 533dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn super.onDestroyView(); 534def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn if (mDialog != null) { 535def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn // Set removed here because this dismissal is just to hide 536def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn // the dialog -- we don't want this to cause the fragment to 537def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn // actually be removed. 538bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn mViewDestroyed = true; 539def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn mDialog.dismiss(); 540def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn mDialog = null; 541def1537e9e8d0dd190cde5310ddae8b921088c9bDianne Hackborn } 542dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn } 543bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn 544bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn @Override 545bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { 546bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn super.dump(prefix, fd, writer, args); 547bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(prefix); writer.println("DialogFragment:"); 548bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(prefix); writer.print(" mStyle="); writer.print(mStyle); 549bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(" mTheme=0x"); writer.println(Integer.toHexString(mTheme)); 550bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(prefix); writer.print(" mCancelable="); writer.print(mCancelable); 551bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(" mShowsDialog="); writer.print(mShowsDialog); 552bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(" mBackStackId="); writer.println(mBackStackId); 553bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(prefix); writer.print(" mDialog="); writer.println(mDialog); 554bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(prefix); writer.print(" mViewDestroyed="); writer.print(mViewDestroyed); 555bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(" mDismissed="); writer.print(mDismissed); 556bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn writer.print(" mShownByMe="); writer.println(mShownByMe); 557bfe2e3f9da507a19f5602f0b267be92ddccdd250Dianne Hackborn } 558dd913a50cd72d6dd23c4ea437f0ebe2be05ca2e8Dianne Hackborn} 559