| page.title=Диалоговые окна |
| page.tags=alertdialog,dialogfragment |
| |
| @jd:body |
| |
| |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>Содержание документа</h2> |
| <ol> |
| <li><a href="#DialogFragment">Создание фрагмента диалогового окна</a></li> |
| <li><a href="#AlertDialog">Создание диалогового окна оповещения</a> |
| <ol> |
| <li><a href="#AddingButtons">Добавление кнопок</a></li> |
| <li><a href="#AddingAList">Добавление списка</a></li> |
| <li><a href="#CustomLayout">Создание пользовательского макета</a></li> |
| </ol> |
| </li> |
| <li><a href="#PassingEvents">Передача событий обратно в основное приложение</a></li> |
| <li><a href="#ShowingADialog">Отображение диалогового окна</a></li> |
| <li><a href="#FullscreenDialog">Отображение диалогового окна в полноэкранном режиме или в виде встроенного фрагмента</a> |
| <ol> |
| <li><a href="#ActivityAsDialog">Отображение операции в качестве диалога на больших экранах</a></li> |
| </ol> |
| </li> |
| <li><a href="#DismissingADialog">Закрытие диалогового окна</a></li> |
| </ol> |
| |
| <h2>Ключевые классы</h2> |
| <ol> |
| <li>{@link android.app.DialogFragment}</li> |
| <li>{@link android.app.AlertDialog}</li> |
| </ol> |
| |
| <h2>См. также:</h2> |
| <ol> |
| <li><a href="{@docRoot}design/building-blocks/dialogs.html">Руководство по дизайну диалоговых окон</a></li> |
| <li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">Элементы выбора</a> (диалоговые окна выбора даты/времени)</li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>Диалоговое окно — это небольшое окно, которое предлагает пользователю |
| принять решение или ввести дополнительную информацию. Диалоговое окно не заполняет весь экран и, |
| как правило, используется при модальных событиях, для продолжения которых требуется действие пользователя.</p> |
| |
| <div class="note design"> |
| <p><strong>Дизайн диалогового окна</strong></p> |
| <p>Подробную информацию о дизайне диалоговых окон, включая рекомендации |
| для вашего языка см. в <a href="{@docRoot}design/building-blocks/dialogs.html">Руководстве</a> по дизайну диалоговых окон.</p> |
| </div> |
| |
| <img src="{@docRoot}images/ui/dialogs.png" /> |
| |
| <p>Класс {@link android.app.Dialog} — это базовый класс для создания диалоговых окон, но |
| реализовывать напрямую класс {@link android.app.Dialog} не рекомендуется. |
| Вместо этого следует использовать один из следующих подклассов:</p> |
| <dl> |
| <dt>{@link android.app.AlertDialog}</dt> |
| <dd>Диалоговое окно, в котором могут отображаться заголовок, кнопки вплоть до трех штук, список |
| из выбираемых элементов либо пользовательский макет.</dd> |
| <dt>{@link android.app.DatePickerDialog} или {@link android.app.TimePickerDialog}</dt> |
| <dd>Диалоговое окно с предопределенным пользовательским интерфейсом, с помощью которого пользователь указывает значения даты или времени.</dd> |
| </dl> |
| |
| <div class="sidebox"> |
| <h2>Следует избегать ProgressDialog</h2> |
| <p>В Android имеется другой класс диалоговых окон под названием |
| {@link android.app.ProgressDialog}, которые отображают диалоговое окно с индикатором выполнения процесса. Тем не менее, если |
| необходимо отобразить прогресс загрузки или неопределенный процес, рекомендуется следовать |
| инструкциям по дизайну <a href="{@docRoot}design/building-blocks/progress.html">Выполнение & |
| Операции</a>, чтобы использовать {@link android.widget.ProgressBar} в вашем макете.</p> |
| </div> |
| |
| <p>Эти классы определяют стиль и структуру вашего диалогового окна, однако следует |
| использовать{@link android.support.v4.app.DialogFragment} в качестве контейнера вашего диалогового окна. |
| Класс {@link android.support.v4.app.DialogFragment} предоставляет все функции, |
| необходимые для создания диалогового окна и управления его внешним видом, вместо вызова методов |
| к объекту{@link android.app.Dialog}.</p> |
| |
| <p>Использование {@link android.support.v4.app.DialogFragment} для управления диалоговым окном |
| обеспечивает корректную обработку событий жизненного цикла |
| , таких как нажатие пользователем кнопки <em>Назад</em> или поворот экрана. С помощью класса {@link |
| android.support.v4.app.DialogFragment} также происходит повторное использование пользовательского интерфейса диалогового окна в качестве |
| встраиваемого компонента в пользовательский интерфейс более высокого уровня — подобно традиционному классу {@link |
| android.support.v4.app.Fragment} (например, когда необходимо различное отображение пользовательского интерфеса диалогового окна |
| на больших и маленьких экранах).</p> |
| |
| <p>В следующих разделах руководства описано использование {@link |
| android.support.v4.app.DialogFragment} в сочетании с объектом {@link android.app.AlertDialog} |
| . Если необходимо создать элемент выбора даты или времени, обратитесь к руководству |
| <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Элементы выбора</a>.</p> |
| |
| <p class="note"><strong>Примечание:</strong> |
| Поскольку класс {@link android.app.DialogFragment} изначально включен в |
| Android 3.0 (уровень API 11), в настоящем документе описывается использование класса {@link |
| android.support.v4.app.DialogFragment}, предоставляемого в <a href="{@docRoot}tools/support-library/index.html">Библиотеке поддержки</a>. После добавления этой библиотеки |
| в приложение появится возможность использовать{@link android.support.v4.app.DialogFragment} и множество других |
| API на устройствах, работающих на Android 1.6 и выше. Если минимальная версия вашего приложения поддерживает |
| уровень API 11 и выше, можно использовать фреймворк-версию {@link |
| android.app.DialogFragment}, но следует иметь в виду, что данный документ ссылается на API |
| со вспомогательными библиотеками. При использовании вспомогательной библиотеки |
| необходимо импортировать класс <code>android.support.v4.app.DialogFragment</code> |
| , а <em>не</em> <code>android.app.DialogFragment</code>.</p> |
| |
| |
| <h2 id="DialogFragment">Создание фрагмента диалогового окна</h2> |
| |
| <p>Вы можете реализовать широкие возможности дизайна диалоговых окон, включая создание |
| пользовательских макетов, а также пути, описанные в руководстве по дизайну <a href="{@docRoot}design/building-blocks/dialogs.html">Диалоговых окон</a> |
| —путем расширения |
| {@link android.support.v4.app.DialogFragment} и создания{@link android.app.AlertDialog} |
| в методе обратного вызова {@link android.support.v4.app.DialogFragment#onCreateDialog |
| onCreateDialog()}.</p> |
| |
| <p>Например, имеется базовый класс {@link android.app.AlertDialog}, управляемый в рамках |
| {@link android.support.v4.app.DialogFragment}:</p> |
| |
| <pre> |
| public class FireMissilesDialogFragment extends DialogFragment { |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| // Use the Builder class for convenient dialog construction |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setMessage(R.string.dialog_fire_missiles) |
| .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // FIRE ZE MISSILES! |
| } |
| }) |
| .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // User cancelled the dialog |
| } |
| }); |
| // Create the AlertDialog object and return it |
| return builder.create(); |
| } |
| } |
| </pre> |
| |
| <div class="figure" style="width:290px;margin:0 0 0 20px"> |
| <img src="{@docRoot}images/ui/dialog_buttons.png" alt="" /> |
| <p class="img-caption"><strong>Рисунок 1.</strong> |
| Диалоговое окно с сообщением и двумя кнопками действия.</p> |
| </div> |
| |
| <p>Итак, после создания экземпляра этого класса и вызова {@link |
| android.support.v4.app.DialogFragment#show show()} к этому объекту появляется диалоговое окно, |
| показанное на рисунке 1.</p> |
| |
| <p>В следующем разделе предоставлена более подробная информация об использовании API {@link android.app.AlertDialog.Builder} |
| для создания диалоговых окон.</p> |
| |
| <p>В зависимости от сложности создаваемого диалогового окна возможно реализовать множество других методов |
| обратного вызова в {@link android.support.v4.app.DialogFragment}, включая все базовые |
| <a href="{@docRoot}guide/components/fragments.html#Lifecycle">методы жизненных циклов фрагментов</a>. |
| |
| |
| |
| |
| |
| <h2 id="AlertDialog">Создание диалогового окна оповещения</h2> |
| |
| |
| <p>С помощью класса {@link android.app.AlertDialog} создается многообразие решений касательно внешнего вида диалогового окна |
| , и зачастую этого класса вполне достаточно. |
| Как показано на рис. 2, диалоговое окно состоит из трех областей:</p> |
| |
| <div class="figure" style="width:311px;margin-top:0"> |
| <img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0" /> |
| <p class="img-caption"><strong>Рисунок 2.</strong> Макет диалогового окна.</p> |
| </div> |
| |
| <ol> |
| <li><b>Заголовок</b> |
| <p>Это дополнительная возможность, которая используется только в случае, если область содержимого |
| занята подробным сообщением, списком или пользовательским макетом. Если необходимо отобразить |
| простое сообщение или вопрос (как, например, в диалоге на рисунке 1), заголовок не нужен.</li> |
| <li><b>Область содержимого</b> |
| <p>Здесь может отображаться сообщение, список или другой пользовательский макет.</p></li> |
| <li><b>Кнопки действия</b> |
| <p>В диалоговом окне не должно содержаться более трех кнопок действия.</p></li> |
| </ol> |
| |
| <p>Класс {@link android.app.AlertDialog.Builder} |
| предоставляет API, с помощью которых можно создавать {@link android.app.AlertDialog} |
| с этими видами содержимого, включая пользовательский макет.</p> |
| |
| <p>Создание {@link android.app.AlertDialog}:</p> |
| |
| <pre> |
| <b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b> |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| |
| <b>// 2. Chain together various setter methods to set the dialog characteristics</b> |
| builder.setMessage(R.string.dialog_message) |
| .setTitle(R.string.dialog_title); |
| |
| <b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b> |
| AlertDialog dialog = builder.create(); |
| </pre> |
| |
| <p>В следующих главах показано, как определять различные атрибуты диалоговых окон с помощью класса |
| {@link android.app.AlertDialog.Builder}.</p> |
| |
| |
| |
| |
| <h3 id="AddingButtons">Добавление кнопок</h3> |
| |
| <p>Для добавления кнопок, изображенных на рисунке 2, |
| вызывайте методы {@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} и |
| {@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()}:</p> |
| |
| <pre style="clear:right"> |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| // Add the buttons |
| builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // User clicked OK button |
| } |
| }); |
| builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // User cancelled the dialog |
| } |
| }); |
| // Set other dialog properties |
| ... |
| |
| // Create the AlertDialog |
| AlertDialog dialog = builder.create(); |
| </pre> |
| |
| <p>Методы <code>set...Button()</code> предполагают заголовок для кнопки (реализуемый |
| через <a href="{@docRoot}guide/topics/resources/string-resource.html">строковый ресурс</a>) и |
| {@link android.content.DialogInterface.OnClickListener}, который определяет действие, |
| следующее за нажатием кнопки пользователем.</p> |
| |
| <p>Реализована возможность добавлять три различных вида кнопок действий:</p> |
| <dl> |
| <dt>Положительные</dt> |
| <dd>Используются для подтверждения и продолжения дейстия (кнопка «ОК»).</dd> |
| <dt>Отрицательные</dt> |
| <dd>Используются для отмены действия.</dd> |
| <dt>Нейтральные</dt> |
| <dd>Используются в случаях, когда пользователь может не желать продолжить действие, |
| но при этом необязательно хочет его отменить. Появляется между положительными и отрицательнымиI |
| кнопками. Примером такого действия может быть «Напомнить позже».</dd> |
| </dl> |
| |
| <p>Можно добавлять только одну кнопку каждого вида в {@link |
| android.app.AlertDialog}. Это означает, что нельзя использовать более одной «положительной» кнопки.</p> |
| |
| |
| |
| <div class="figure" style="width:290px;margin:0 0 0 40px"> |
| <img src="{@docRoot}images/ui/dialog_list.png" alt="" /> |
| <p class="img-caption"><strong>Рисунок 3.</strong> |
| Диалоговое окно с заголовком и списком.</p> |
| </div> |
| |
| <h3 id="AddingAList">Добавление списка</h3> |
| |
| <p>В API {@link android.app.AlertDialog} реализована возможность использования трех видов списков:</p> |
| <ul> |
| <li>Традиционный список с выбором одного варианта</li> |
| <li>Интерактивный список с выбором одного варианта (переключатели)</li> |
| <li>Интерактивный список с выбором нескольких вариантов (флажки)</li> |
| </ul> |
| |
| <p>Для создания списка с выбором одного варианта, как на рисунке 3, |
| используйте метод{@link android.app.AlertDialog.Builder#setItems setItems()}:</p> |
| |
| <pre style="clear:right"> |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setTitle(R.string.pick_color) |
| .setItems(R.array.colors_array, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int which) { |
| // The 'which' argument contains the index position |
| // of the selected item |
| } |
| }); |
| return builder.create(); |
| } |
| </pre> |
| |
| <p>Поскольку список отображается в области содержимого диалогового окна, |
| диалоговое окно не может показать одновременно сообщение и список, поэтому необходимо задать заголовок |
| диалогового окна с помощью {@link android.app.AlertDialog.Builder#setTitle setTitle()}. |
| Для указания элементов списка необходимо вызвать {@link |
| android.app.AlertDialog.Builder#setItems setItems()}, передающий указатель. |
| В качестве другого варианта можно указать список с помощью {@link |
| android.app.AlertDialog.Builder#setAdapter setAdapter()}. Наполнение списка |
| динамическими данными (например, из базы данных) происходит с помощью {@link android.widget.ListAdapter}.</p> |
| |
| <p>Если вы предпочтете реализовать список с помощью {@link android.widget.ListAdapter}, |
| рекомендуется использовать {@link android.support.v4.content.Loader}, чтобы содержимое загружалось |
| асинхронно. Подробно этот процесс описан далее в руководстве по |
| <a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Созданию макетов |
| с помощью адаптера</a> и <a href="{@docRoot}guide/components/loaders.html">загрузчиков</a> |
| .</p> |
| |
| <p class="note"><strong>Примечание:</strong> По умолчанию нажатие по элементу списка отменяет диалоговое окно, |
| за исключением случаев, когда используется один из следующих интерактивных списков.</p> |
| |
| <div class="figure" style="width:290px;margin:-30px 0 0 40px"> |
| <img src="{@docRoot}images/ui/dialog_checkboxes.png" /> |
| <p class="img-caption"><strong>Рисунок 4.</strong> |
| Список с несколькими вариантами ответов.</p> |
| </div> |
| |
| |
| <h4 id="Checkboxes">Добавление интерактивного списка с одним или несколькими вариантами ответов</h4> |
| |
| <p>Для добавления списка с несколькими вариантами ответов (флажки) или |
| списка с одним вариантом ответа (переключатели) используйте методы |
| {@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String, |
| DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} или |
| {@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) |
| setSingleChoiceItems()} соответственно.</p> |
| |
| <p>Например, таким образом можно создать список с несколькими вариантами ответов, как на |
| рисунке 4, который сохраняет выбранные |
| элементы в {@link java.util.ArrayList}:</p> |
| |
| <pre style="clear:right"> |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| mSelectedItems = new ArrayList(); // Where we track the selected items |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| // Set the dialog title |
| builder.setTitle(R.string.pick_toppings) |
| // Specify the list array, the items to be selected by default (null for none), |
| // and the listener through which to receive callbacks when items are selected |
| .setMultiChoiceItems(R.array.toppings, null, |
| new DialogInterface.OnMultiChoiceClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which, |
| boolean isChecked) { |
| if (isChecked) { |
| // If the user checked the item, add it to the selected items |
| mSelectedItems.add(which); |
| } else if (mSelectedItems.contains(which)) { |
| // Else, if the item is already in the array, remove it |
| mSelectedItems.remove(Integer.valueOf(which)); |
| } |
| } |
| }) |
| // Set the action buttons |
| .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int id) { |
| // User clicked OK, so save the mSelectedItems results somewhere |
| // or return them to the component that opened the dialog |
| ... |
| } |
| }) |
| .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int id) { |
| ... |
| } |
| }); |
| |
| return builder.create(); |
| } |
| </pre> |
| |
| <p>Несмотря на то, что и традиционный список, и список с переключателями |
| предполагают действие по выбору одного элемента, вам необходимо использовать {@link |
| android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener) |
| setSingleChoiceItems()}, чтобы сохранить выбор пользователя. |
| Это значит, что при повторном открытии диалогового окна будет отображаться текущий выбор пользователя, |
| а затем создается список с переключателями.</p> |
| |
| |
| |
| |
| |
| <h3 id="CustomLayout">Создание пользовательского макета</h3> |
| |
| <div class="figure" style="width:290px;margin:-30px 0 0 40px"> |
| <img src="{@docRoot}images/ui/dialog_custom.png" alt="" /> |
| <p class="img-caption"><strong>Рисунок 5</strong>. Пользовательский макет диалогового окна.</p> |
| </div> |
| |
| <p>Если в диалоговом окне необходим пользовательский макет, нужно создать макет и добавить его в |
| {@link android.app.AlertDialog} путем вызова {@link |
| android.app.AlertDialog.Builder#setView setView()} в объекте {@link |
| android.app.AlertDialog.Builder}.</p> |
| |
| <p>По умолчанию пользовательский мает заполняет окно диалога, при это все равно можно |
| использовать методы {@link android.app.AlertDialog.Builder} для добавления кнопок и заголовка.</p> |
| |
| <p>В качестве примера на рисунке 5 приведен файл макета для диалогового окна.</p> |
| |
| <p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p> |
| <pre> |
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| android:orientation="vertical" |
| android:layout_width="wrap_content" |
| android:layout_height="wrap_content"> |
| <ImageView |
| android:src="@drawable/header_logo" |
| android:layout_width="match_parent" |
| android:layout_height="64dp" |
| android:scaleType="center" |
| android:background="#FFFFBB33" |
| android:contentDescription="@string/app_name" /> |
| <EditText |
| android:id="@+id/username" |
| android:inputType="textEmailAddress" |
| android:layout_width="match_parent" |
| android:layout_height="wrap_content" |
| android:layout_marginTop="16dp" |
| android:layout_marginLeft="4dp" |
| android:layout_marginRight="4dp" |
| android:layout_marginBottom="4dp" |
| android:hint="@string/username" /> |
| <EditText |
| android:id="@+id/password" |
| android:inputType="textPassword" |
| android:layout_width="match_parent" |
| android:layout_height="wrap_content" |
| android:layout_marginTop="4dp" |
| android:layout_marginLeft="4dp" |
| android:layout_marginRight="4dp" |
| android:layout_marginBottom="16dp" |
| android:fontFamily="sans-serif" |
| android:hint="@string/password"/> |
| </LinearLayout> |
| </pre> |
| |
| <p class="note"><strong>Совет.</strong> По умолчанию при настройке элемента {@link android.widget.EditText} |
| для типа ввода {@code "textPassword"} используется семейство шрифтов фиксированной ширины, поэтому |
| необходимо изменить семейство шрифтов на{@code "sans-serif"}, чтобы в обоих текстовых полях использовались |
| одинаковые стили шрифта.</p> |
| |
| <p>Для применения макета в вашем {@link android.support.v4.app.DialogFragment} |
| вам понадобится {@link android.view.LayoutInflater} с |
| {@link android.app.Activity#getLayoutInflater()} и вызов |
| {@link android.view.LayoutInflater#inflate inflate()}, где первым параметром будет являться |
| ID ресурса макета, а вторым параметром — исходный вид макета. |
| Затем можно вызвать{@link android.app.AlertDialog#setView setView()} |
| для размещения макета в диалоговом окне.</p> |
| |
| <pre> |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| // Get the layout inflater |
| LayoutInflater inflater = getActivity().getLayoutInflater(); |
| |
| // Inflate and set the layout for the dialog |
| // Pass null as the parent view because its going in the dialog layout |
| builder.setView(inflater.inflate(R.layout.dialog_signin, null)) |
| // Add action buttons |
| .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int id) { |
| // sign in the user ... |
| } |
| }) |
| .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| LoginDialogFragment.this.getDialog().cancel(); |
| } |
| }); |
| return builder.create(); |
| } |
| </pre> |
| |
| <div class="note"> |
| <p><strong>Совет.</strong> Если необходимо пользовательское диалоговое окно, |
| можно отображать {@link android.app.Activity} в качестве диалога |
| вместо API {@link android.app.Dialog}. Нужно создать операцию и установить тему |
| {@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog} |
| в элементе манифеста<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code |
| <операция>}</a>:</p> |
| |
| <pre> |
| <activity android:theme="@android:style/Theme.Holo.Dialog" > |
| </pre> |
| <p>Готово. Операция теперь отображается в диалоговом окне, а не в полноэкранном режиме.</p> |
| </div> |
| |
| |
| |
| <h2 id="PassingEvents">Передача событий обратно в основное диалоговое приложение</h2> |
| |
| <p>Когда пользователь нажимает одну из кнопок действий в диалоговом окне, либо выбирает элемент из списка, |
| {@link android.support.v4.app.DialogFragment} может самостоятельно произвести необходимое |
| действие, однако зачастую вам может понадобиться доставить информацию о событии операции или фрагменту, которые |
| открыли диалоговое окно. Для этого нобходимо определить интерфейс метода для каждого типа события нажатия. |
| Затем этот интерфейс применяется в основном компоненте приложения, которое |
| получает информацию о событиях из диалогового окна.</p> |
| |
| <p>Например, {@link android.support.v4.app.DialogFragment} определяет |
| интерфейс, по который доставляет события обратно в основной компонент операции:</p> |
| |
| <pre> |
| public class NoticeDialogFragment extends DialogFragment { |
| |
| /* The activity that creates an instance of this dialog fragment must |
| * implement this interface in order to receive event callbacks. |
| * Each method passes the DialogFragment in case the host needs to query it. */ |
| public interface NoticeDialogListener { |
| public void onDialogPositiveClick(DialogFragment dialog); |
| public void onDialogNegativeClick(DialogFragment dialog); |
| } |
| |
| // Use this instance of the interface to deliver action events |
| NoticeDialogListener mListener; |
| |
| // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener |
| @Override |
| public void onAttach(Activity activity) { |
| super.onAttach(activity); |
| // Verify that the host activity implements the callback interface |
| try { |
| // Instantiate the NoticeDialogListener so we can send events to the host |
| mListener = (NoticeDialogListener) activity; |
| } catch (ClassCastException e) { |
| // The activity doesn't implement the interface, throw exception |
| throw new ClassCastException(activity.toString() |
| + " must implement NoticeDialogListener"); |
| } |
| } |
| ... |
| } |
| </pre> |
| |
| <p>Операция, выполняемая диалоговым окном, создает экземпляр диалогового окна |
| с помощью конструктора фрагментов диалогового окна и получает события |
| диалога с помощью реализации интерфейса {@code NoticeDialogListener}:</p> |
| |
| <pre> |
| public class MainActivity extends FragmentActivity |
| implements NoticeDialogFragment.NoticeDialogListener{ |
| ... |
| |
| public void showNoticeDialog() { |
| // Create an instance of the dialog fragment and show it |
| DialogFragment dialog = new NoticeDialogFragment(); |
| dialog.show(getSupportFragmentManager(), "NoticeDialogFragment"); |
| } |
| |
| // The dialog fragment receives a reference to this Activity through the |
| // Fragment.onAttach() callback, which it uses to call the following methods |
| // defined by the NoticeDialogFragment.NoticeDialogListener interface |
| @Override |
| public void onDialogPositiveClick(DialogFragment dialog) { |
| // User touched the dialog's positive button |
| ... |
| } |
| |
| @Override |
| public void onDialogNegativeClick(DialogFragment dialog) { |
| // User touched the dialog's negative button |
| ... |
| } |
| } |
| </pre> |
| |
| <p>Поскольку выполняемая операция реализуется через {@code NoticeDialogListener} |
| с помощью метода обратного вызова |
| {@link android.support.v4.app.Fragment#onAttach onAttach()}, во фрагменте диалога могут использоваться |
| методы обратного вызова интерфейса для доставки событий нажатий к операциям:</p> |
| |
| <pre> |
| public class NoticeDialogFragment extends DialogFragment { |
| ... |
| |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| // Build the dialog and set up the button click handlers |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setMessage(R.string.dialog_fire_missiles) |
| .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // Send the positive button event back to the host activity |
| mListener.onDialogPositiveClick(NoticeDialogFragment.this); |
| } |
| }) |
| .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| public void onClick(DialogInterface dialog, int id) { |
| // Send the negative button event back to the host activity |
| mListener.onDialogNegativeClick(NoticeDialogFragment.this); |
| } |
| }); |
| return builder.create(); |
| } |
| } |
| </pre> |
| |
| |
| |
| <h2 id="ShowingADialog">Отображение диалогового окна</h2> |
| |
| <p>Для отображения диалогового окна необходимо создать экземпляр {@link |
| android.support.v4.app.DialogFragment} и вызвать {@link android.support.v4.app.DialogFragment#show |
| show()}, передавая {@link android.support.v4.app.FragmentManager} и наименование тега |
| для фрагмента диалога.</p> |
| |
| <p>Можно получить {@link android.support.v4.app.FragmentManager} путем вызова |
| {@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()} из |
| {@link android.support.v4.app.FragmentActivity} или {@link |
| android.support.v4.app.Fragment#getFragmentManager()} из {@link |
| android.support.v4.app.Fragment}. Пример:</p> |
| |
| <pre> |
| public void confirmFireMissiles() { |
| DialogFragment newFragment = new FireMissilesDialogFragment(); |
| newFragment.show(getSupportFragmentManager(), "missiles"); |
| } |
| </pre> |
| |
| <p>Второй аргумент, {@code "missiles"}, — это уникальное наименование тега, которое система использует для сохранения |
| и восстановления состояния фрагмента, когда это необходимо. С помощью этого тега также можно управлять |
| фрагментом путем вызова {@link android.support.v4.app.FragmentManager#findFragmentByTag |
| findFragmentByTag()}.</p> |
| |
| |
| |
| |
| <h2 id="FullscreenDialog">Отображение диалогового окна в полноэкранном режиме или в виде встроенного фрагмента</h2> |
| |
| <p>Вам может понадобиться макет пользовательского интерфейса, в котором в некоторых ситуациях часть пользовательского интерфейса должна появляться как диалоговое окно |
| , отображаемое в полноэкранном режиме либо в виде встроенного фрагмента (возможно, в зависимости от того, |
| маленький или большой экран у устройства). С помощью класса {@link android.support.v4.app.DialogFragment} |
| обеспечивается гибкость решения, поскольку он может вести себя как встраиваемый {@link |
| android.support.v4.app.Fragment}.</p> |
| |
| <p>Тем не менее, в этом случае нельзя использовать{@link android.app.AlertDialog.Builder AlertDialog.Builder} |
| или другие объекты {@link android.app.Dialog} для построения диалогового окна. Если |
| необходимо сделать {@link android.support.v4.app.DialogFragment} |
| встраиваемым, нужно определить пользовательский интерфейс диалогового окна в макете методом обратного вызова |
| {@link android.support.v4.app.DialogFragment#onCreateView |
| onCreateView()}.</p> |
| |
| <p>В качестве примера приведен {@link android.support.v4.app.DialogFragment}, который появляется либо в виде |
| диалогового окна, либо в виде встраиваемого фрагмента (используя макет с наименованием <code>purchase_items.xml</code>):</p> |
| |
| <pre> |
| public class CustomDialogFragment extends DialogFragment { |
| /** The system calls this to get the DialogFragment's layout, regardless |
| of whether it's being displayed as a dialog or an embedded fragment. */ |
| @Override |
| public View onCreateView(LayoutInflater inflater, ViewGroup container, |
| Bundle savedInstanceState) { |
| // Inflate the layout to use as dialog or embedded fragment |
| return inflater.inflate(R.layout.purchase_items, container, false); |
| } |
| |
| /** The system calls this only when creating the layout in a dialog. */ |
| @Override |
| public Dialog onCreateDialog(Bundle savedInstanceState) { |
| // The only reason you might override this method when using onCreateView() is |
| // to modify any dialog characteristics. For example, the dialog includes a |
| // title by default, but your custom layout might not need it. So here you can |
| // remove the dialog title, but you must call the superclass to get the Dialog. |
| Dialog dialog = super.onCreateDialog(savedInstanceState); |
| dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); |
| return dialog; |
| } |
| } |
| </pre> |
| |
| <p>Приведен пример кода, реализующего принятие решения об отображении фргмента в качестве диалогового окна |
| или полноэкранного пользовательского интерфейса на основе размера экрана:</p> |
| |
| <pre> |
| public void showDialog() { |
| FragmentManager fragmentManager = getSupportFragmentManager(); |
| CustomDialogFragment newFragment = new CustomDialogFragment(); |
| |
| if (mIsLargeLayout) { |
| // The device is using a large layout, so show the fragment as a dialog |
| newFragment.show(fragmentManager, "dialog"); |
| } else { |
| // The device is smaller, so show the fragment fullscreen |
| FragmentTransaction transaction = fragmentManager.beginTransaction(); |
| // For a little polish, specify a transition animation |
| transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); |
| // To make it fullscreen, use the 'content' root view as the container |
| // for the fragment, which is always the root view for the activity |
| transaction.add(android.R.id.content, newFragment) |
| .addToBackStack(null).commit(); |
| } |
| } |
| </pre> |
| |
| <p>Подробные сведения о выполнении операций с фрагментами приведены в руководстве |
| <a href="{@docRoot}guide/components/fragments.html">Фрагменты</a>.</p> |
| |
| <p>В приведенном примере <code>mIsLargeLayout</code> булеан указывает, должно ли текущее устройство использовать |
| большой макет приложения (и отображать фрагмент как диалоговое окно, а не |
| в полноэкранном режиме). Лучшим способом установить такой вид булеана является объявление |
| <a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">значения булевой переменной</a> |
| с <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">альтернативным</a> значением для других размеров экранов. В качестве примера приведены два |
| варианта булевых ресурсов для различных размеров экранов:</p> |
| |
| <p class="code-caption">res/values/bools.xml</p> |
| <pre> |
| <!-- Default boolean values --> |
| <resources> |
| <bool name="large_layout">false</bool> |
| </resources> |
| </pre> |
| |
| <p class="code-caption">res/values-large/bools.xml</p> |
| <pre> |
| <!-- Large screen boolean values --> |
| <resources> |
| <bool name="large_layout">true</bool> |
| </resources> |
| </pre> |
| |
| <p>Затем можно инизиализировать значение {@code mIsLargeLayout} в течение выполнения метода операции |
| {@link android.app.Activity#onCreate onCreate()}:</p> |
| |
| <pre> |
| boolean mIsLargeLayout; |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| setContentView(R.layout.activity_main); |
| |
| mIsLargeLayout = getResources().getBoolean(R.bool.large_layout); |
| } |
| </pre> |
| |
| |
| |
| <h3 id="ActivityAsDialog">Отображение операции в качестве диалога на больших экранах</h3> |
| |
| <p>Вместо отображения диалогового окна в полноэкранном режиме на экранах малого размера можно |
| отображать {@link android.app.Activity} в качестве диалогового окна на |
| экранах большого размера. Выбор зависит от дизайна приложения, но |
| отображение операции в качестве диалогового окна имеет смысл, когда приложение предназначено для использования на малых |
| экранах, и необходимо улучшить взаимодейтсвие с ним на планшетах, показывая кратковременные операции |
| в качестве диалогового окна.</p> |
| |
| <p>Для отображения операции в качестве диалогового окна только на больших экранах |
| необходимо применить тему {@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge} |
| к элементу манифеста <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code |
| <операция>}</a>:</p> |
| |
| <pre> |
| <activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" > |
| </pre> |
| |
| <p>Подробная информация о темах операций приведена в руководстве <a href="{@docRoot}guide/topics/ui/themes.html">Стили и темы</a>.</p> |
| |
| |
| |
| <h2 id="DismissingADialog">Закрытие диалогового окна</h2> |
| |
| <p>Когда пользователь нажимает кнопки, созданные с помощью |
| {@link android.app.AlertDialog.Builder}, система закрывает диалоговое окно самостоятельно.</p> |
| |
| <p>Система также закрывает диалоговое окно, когда пользователь нажимает на элемент списка в диалоговом окне, за исключением |
| списков с переключателями или флажками. В иных случаях можно вручную закрыть диалоговое окно |
| путем вызова {@link android.support.v4.app.DialogFragment#dismiss()} в {@link |
| android.support.v4.app.DialogFragment}.</p> |
| |
| <p>В случае, если необходимо произвести определенные |
| действия после закрытия диалогового окна, можно реализовать метод {@link |
| android.support.v4.app.DialogFragment#onDismiss onDismiss()} в {@link |
| android.support.v4.app.DialogFragment}.</p> |
| |
| <p>Также можно <em>отменить</em> диалоговое окно. Это особое событие, возникающее, когда пользователь |
| покинул диалоговое окно, не завершив задачу. Так происходит, когда пользователь нажимает кнопку |
| <em>Назад</em>, касается экрана за областью диалогового окна, |
| либо когда задано {@link android.app.Dialog#cancel()} в {@link |
| android.app.Dialog} (например, в качестве отклика на нажатие кнопки «Отмена» в диалоговом окне).</p> |
| |
| <p>Как показано в примере выше, можно ответить на событие отмены с помощью |
| {@link android.support.v4.app.DialogFragment#onCancel onCancel()} в классе {@link |
| android.support.v4.app.DialogFragment}.</p> |
| |
| <p class="note"><strong>Примечание:</strong> Система вызывает |
| {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} при каждом событии, |
| которое вызывается методом обратного вызова{@link android.support.v4.app.DialogFragment#onCancel onCancel()}. Тем не менее, |
| при вызове{@link android.app.Dialog#dismiss Dialog.dismiss()} или {@link |
| android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()}, |
| система вызывает {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} <em>, а |
| не</em> {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. Поэтому в общих случаях |
| вызов{@link android.support.v4.app.DialogFragment#dismiss dismiss()} производится при нажатии пользователем |
| <em>положительной</em> кнопки в диалоговом окне, а после диалоговое окно закрывается.</p> |
| |
| |