Диалоговое окно — это небольшое окно, предлагающее пользователю принять решение или ввести дополнительную информацию. Диалоговое окно не заполняет весь экран и обычно используется для модальных событий, требующих от пользователя выполнения какого-либо действия перед продолжением.
Класс Dialog является базовым классом для диалоговых окон, но не следует создавать экземпляр Dialog напрямую. Вместо этого используйте один из следующих подклассов:
-
AlertDialog - Диалоговое окно, которое может отображать заголовок, до трех кнопок, список выбираемых элементов или настраиваемый макет.
-
DatePickerDialogилиTimePickerDialog - Диалоговое окно с предопределенным пользовательским интерфейсом, позволяющее пользователю выбрать дату или время.
Эти классы определяют стиль и структуру вашего диалогового окна. Вам также потребуется DialogFragment в качестве контейнера для вашего диалогового окна. Класс DialogFragment предоставляет все необходимые элементы управления для создания диалогового окна и управления его внешним видом, вместо вызова методов объекта Dialog .
Использование DialogFragment для управления диалоговым окном позволяет корректно обрабатывать события жизненного цикла, такие как нажатие пользователем кнопки «Назад» или поворот экрана. Класс DialogFragment также позволяет повторно использовать пользовательский интерфейс диалогового окна в качестве встраиваемого компонента в более крупный пользовательский интерфейс — подобно традиционному Fragment — например, когда необходимо, чтобы интерфейс диалогового окна отображался по-разному на больших и маленьких экранах.
В следующих разделах этого документа описывается, как использовать DialogFragment в сочетании с объектом AlertDialog . Если вы хотите создать средство выбора даты или времени, прочтите раздел «Добавление средств выбора в ваше приложение» .
Создайте фрагмент диалога
Вы можете реализовать самые разнообразные варианты оформления диалоговых окон, включая пользовательские макеты и варианты, описанные в Material Design Dialogs , расширив DialogFragment и создав AlertDialog в методе обратного вызова onCreateDialog() .
Например, вот простой AlertDialog , управляемый внутри DialogFragment :
Котлин
class StartGameDialogFragment : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { // Use the Builder class for convenient dialog construction. val builder = AlertDialog.Builder(it) builder.setMessage("Start game") .setPositiveButton("Start") { dialog, id -> // START THE GAME! } .setNegativeButton("Cancel") { dialog, id -> // User cancelled the dialog. } // Create the AlertDialog object and return it. builder.create() } ?: throw IllegalStateException("Activity cannot be null") } } class OldXmlActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_old_xml) StartGameDialogFragment().show(supportFragmentManager, "GAME_DIALOG") } }
Java
public class StartGameDialogFragment 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_start_game) .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // START THE GAME! } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancels the dialog. } }); // Create the AlertDialog object and return it. return builder.create(); } } // ... StartGameDialogFragment().show(supportFragmentManager, "GAME_DIALOG");
При создании экземпляра этого класса и вызове метода show() для этого объекта появляется диалоговое окно, как показано на следующем рисунке.

В следующем разделе более подробно описано использование API AlertDialog.Builder для создания диалогового окна.
В зависимости от сложности вашего диалога, вы можете реализовать множество других методов обратного вызова в DialogFragment , включая все основные методы жизненного цикла фрагмента .
Создать диалоговое окно оповещения
Класс AlertDialog позволяет создавать различные варианты диалоговых окон и часто является единственным необходимым классом диалогового окна. Как показано на следующем рисунке, диалоговое окно предупреждения состоит из трех областей:
- Заголовок: это необязательный параметр, используемый только в том случае, если область контента занята подробным сообщением, списком или пользовательским макетом. Если вам нужно изложить простое сообщение или задать вопрос, заголовок не требуется.
- Область контента: здесь можно отображать сообщение, список или другой настраиваемый макет.
- Кнопки действий: в диалоговом окне может быть до трех кнопок действий.
Класс AlertDialog.Builder предоставляет API, позволяющие создавать диалоговые окна AlertDialog с подобным содержимым, включая настраиваемый макет.
Для создания AlertDialog выполните следующие действия:
Котлин
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setMessage("I am the message") .setTitle("I am the title") val dialog: AlertDialog = builder.create() dialog.show()
Java
// 1. Instantiate an AlertDialog.Builder with its constructor. AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // 2. Chain together various setter methods to set the dialog characteristics. builder.setMessage(R.string.dialog_message) .setTitle(R.string.dialog_title); // 3. Get the AlertDialog. AlertDialog dialog = builder.create();
Предыдущий фрагмент кода генерирует следующее диалоговое окно:

Добавить кнопки
Чтобы добавить кнопки действий, подобные показанным на рисунке 2, вызовите методы setPositiveButton() и setNegativeButton() :
Котлин
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setMessage("I am the message") .setTitle("I am the title") .setPositiveButton("Positive") { dialog, which -> // Do something. } .setNegativeButton("Negative") { dialog, which -> // Do something else. } val dialog: AlertDialog = builder.create() dialog.show()
Java
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 taps OK button. } }); builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancels the dialog. } }); // Set other dialog properties. ... // Create the AlertDialog. AlertDialog dialog = builder.create();
Для работы методов set...Button() требуется заголовок кнопки (предоставляемый строковым ресурсом ) и DialogInterface.OnClickListener , определяющий действие, которое должно быть выполнено при нажатии пользователем кнопки.
Можно добавить три кнопки действий:
- Положительный эффект: используйте это, чтобы принять и продолжить действие (действие «ОК»).
- Отрицание: используйте это для отмены действия.
- Нейтральный вариант: используйте его, когда пользователь, возможно, не хочет продолжать действие, но и не обязательно хочет его отменить. Он располагается между положительной и отрицательной кнопками. Например, действие может быть «Напомнить позже».
В AlertDialog можно добавить только по одной кнопке каждого типа. Например, нельзя добавить более одной «положительной» кнопки.
Предыдущий фрагмент кода выводит на экран диалоговое окно с предупреждением, подобное следующему:

Добавить список
В API AlertDialog доступны три типа списков:
- Традиционный список с одним вариантом ответа.
- Постоянно отображаемый список с одним вариантом выбора (переключатели).
- Постоянно отображаемый список вариантов ответа (флажки).
Для создания списка с одним вариантом ответа, подобного показанному на рисунке 5, используйте метод setItems() :
Котлин
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setTitle("I am the title") .setPositiveButton("Positive") { dialog, which -> // Do something. } .setNegativeButton("Negative") { dialog, which -> // Do something else. } .setItems(arrayOf("Item One", "Item Two", "Item Three")) { dialog, which -> // Do something on item tapped. } val dialog: AlertDialog = builder.create() dialog.show()
Java
@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(); }
Этот фрагмент кода генерирует диалоговое окно следующего вида:

Поскольку список отображается в области содержимого диалогового окна, диалоговое окно не может одновременно отображать сообщение и список. Задайте заголовок для диалогового окна с помощью setTitle() . Чтобы указать элементы списка, вызовите setItems() , передав массив. В качестве альтернативы вы можете указать список с помощью setAdapter() . Это позволяет использовать динамические данные для списка, например, из базы данных, с помощью ListAdapter .
Если вы используете ListAdapter в качестве основы для своего списка, всегда используйте Loader , чтобы содержимое загружалось асинхронно. Это более подробно описано в разделе «Создание макетов с помощью адаптера и Loader» .
Добавьте постоянно отображаемый список с несколькими вариантами ответа или с одним вариантом ответа.
Для добавления списка вариантов с несколькими вариантами ответа (флажки) или вариантов с одним вариантом ответа (переключатели) используйте методы setMultiChoiceItems() или setSingleChoiceItems() соответственно.
Например, вот как можно создать список с несколькими вариантами ответа, подобный показанному на рисунке 6, который сохраняет выбранные элементы в ArrayList :
Котлин
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setTitle("I am the title") .setPositiveButton("Positive") { dialog, which -> // Do something. } .setNegativeButton("Negative") { dialog, which -> // Do something else. } .setMultiChoiceItems( arrayOf("Item One", "Item Two", "Item Three"), null) { dialog, which, isChecked -> // Do something. } val dialog: AlertDialog = builder.create() dialog.show()
Java
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { selectedItems = 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 checks the item, add it to the selected // items. selectedItems.add(which); } else if (selectedItems.contains(which)) { // If the item is already in the array, remove it. selectedItems.remove(which); } } }) // Set the action buttons .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { // User taps OK, so save the selectedItems results // somewhere or return them to the component that opens the // dialog. ... } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { ... } }); return builder.create(); }

Диалоговое окно с одним вариантом ответа может выглядеть следующим образом:
Котлин
val builder: AlertDialog.Builder = AlertDialog.Builder(context) builder .setTitle("I am the title") .setPositiveButton("Positive") { dialog, which -> // Do something. } .setNegativeButton("Negative") { dialog, which -> // Do something else. } .setSingleChoiceItems( arrayOf("Item One", "Item Two", "Item Three"), 0 ) { dialog, which -> // Do something. } val dialog: AlertDialog = builder.create() dialog.show()
Java
String[] choices = {"Item One", "Item Two", "Item Three"}; AlertDialog.Builder builder = AlertDialog.Builder(context); builder .setTitle("I am the title") .setPositiveButton("Positive", (dialog, which) -> { }) .setNegativeButton("Negative", (dialog, which) -> { }) .setSingleChoiceItems(choices, 0, (dialog, which) -> { }); AlertDialog dialog = builder.create(); dialog.show();
В результате получается следующий пример:

Создайте пользовательский макет
Если вам нужен пользовательский макет в диалоговом окне, создайте макет и добавьте его в AlertDialog , вызвав setView() для объекта AlertDialog.Builder .

По умолчанию пользовательский макет заполняет диалоговое окно, но вы все еще можете использовать методы AlertDialog.Builder для добавления кнопок и заголовка.
Например, вот файл макета для указанного выше пользовательского макета диалогового окна:
res/layout/dialog_signin.xml
<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>
Чтобы создать макет в вашем DialogFragment , получите LayoutInflater с помощью getLayoutInflater() и вызовите inflate() . Первый параметр — это идентификатор ресурса макета, а второй — родительское представление для макета. Затем вы можете вызвать setView() , чтобы разместить макет в диалоговом окне. Это показано в следующем примере.
Котлин
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { val builder = AlertDialog.Builder(it) // Get the layout inflater. val inflater = requireActivity().layoutInflater; // Inflate and set the layout for the dialog. // Pass null as the parent view because it's going in the dialog // layout. builder.setView(inflater.inflate(R.layout.dialog_signin, null)) // Add action buttons. .setPositiveButton(R.string.signin, DialogInterface.OnClickListener { dialog, id -> // Sign in the user. }) .setNegativeButton(R.string.cancel, DialogInterface.OnClickListener { dialog, id -> getDialog().cancel() }) builder.create() } ?: throw IllegalStateException("Activity cannot be null") }
Java
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // Get the layout inflater. LayoutInflater inflater = requireActivity().getLayoutInflater(); // Inflate and set the layout for the dialog. // Pass null as the parent view because it's 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(); }
Если вам нужен пользовательский диалог, вы можете вместо использования API Dialog отобразить Activity в виде диалога. Создайте Activity и установите для нее тему Theme.Holo.Dialog в элементе манифеста <activity> :
<activity android:theme="@android:style/Theme.Holo.Dialog" >
Теперь действие отображается в диалоговом окне, а не в полноэкранном режиме.
Передайте события обратно хосту диалога.
Когда пользователь нажимает на одну из кнопок действий в диалоговом окне или выбирает элемент из его списка, ваш DialogFragment может выполнить необходимое действие самостоятельно, но часто вам нужно передать событие активности или фрагменту, который открывает диалоговое окно. Для этого определите интерфейс с методом для каждого типа события клика. Затем реализуйте этот интерфейс в компоненте-хосте, который получает события действий от диалогового окна.
Например, вот DialogFragment , который определяет интерфейс, через который он передает события обратно в хост-активность:
Котлин
class NoticeDialogFragment : DialogFragment() { // Use this instance of the interface to deliver action events. internal lateinit var listener: NoticeDialogListener // The activity that creates an instance of this dialog fragment must // implement this interface to receive event callbacks. Each method passes // the DialogFragment in case the host needs to query it. interface NoticeDialogListener { fun onDialogPositiveClick(dialog: DialogFragment) fun onDialogNegativeClick(dialog: DialogFragment) } // Override the Fragment.onAttach() method to instantiate the // NoticeDialogListener. override fun onAttach(context: Context) { super.onAttach(context) // Verify that the host activity implements the callback interface. try { // Instantiate the NoticeDialogListener so you can send events to // the host. listener = context as NoticeDialogListener } catch (e: ClassCastException) { // The activity doesn't implement the interface. Throw exception. throw ClassCastException((context.toString() + " must implement NoticeDialogListener")) } } }
Java
public class NoticeDialogFragment extends DialogFragment { // The activity that creates an instance of this dialog fragment must // implement this interface 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 listener; // Override the Fragment.onAttach() method to instantiate the // NoticeDialogListener. @Override public void onAttach(Context context) { super.onAttach(context); // Verify that the host activity implements the callback interface. try { // Instantiate the NoticeDialogListener so you can send events to // the host. listener = (NoticeDialogListener) context; } catch (ClassCastException e) { // The activity doesn't implement the interface. Throw exception. throw new ClassCastException(activity.toString() + " must implement NoticeDialogListener"); } } ... }
Активность, размещающая диалоговое окно, создает экземпляр диалогового окна с помощью конструктора фрагмента диалогового окна и получает события диалогового окна через реализацию интерфейса NoticeDialogListener :
Котлин
class MainActivity : FragmentActivity(), NoticeDialogFragment.NoticeDialogListener { fun showNoticeDialog() { // Create an instance of the dialog fragment and show it. val dialog = NoticeDialogFragment() dialog.show(supportFragmentManager, "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 fun onDialogPositiveClick(dialog: DialogFragment) { // User taps the dialog's positive button. } override fun onDialogNegativeClick(dialog: DialogFragment) { // User taps the dialog's negative button. } }
Java
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 taps the dialog's positive button. ... } @Override public void onDialogNegativeClick(DialogFragment dialog) { // User taps the dialog's negative button. ... } }
Поскольку основная активность реализует интерфейс NoticeDialogListener , что обеспечивается методом обратного вызова onAttach() , показанным в предыдущем примере, фрагмент диалога может использовать методы обратного вызова интерфейса для передачи событий клика в активность:
Котлин
override fun onCreateDialog(savedInstanceState: Bundle): Dialog { return activity?.let { // Build the dialog and set up the button click handlers. val builder = AlertDialog.Builder(it) builder.setMessage(R.string.dialog_start_game) .setPositiveButton(R.string.start, DialogInterface.OnClickListener { dialog, id -> // Send the positive button event back to the // host activity. listener.onDialogPositiveClick(this) }) .setNegativeButton(R.string.cancel, DialogInterface.OnClickListener { dialog, id -> // Send the negative button event back to the // host activity. listener.onDialogNegativeClick(this) }) builder.create() } ?: throw IllegalStateException("Activity cannot be null") }
Java
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_start_game) .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Send the positive button event back to the host activity. listener.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. listener.onDialogNegativeClick(NoticeDialogFragment.this); } }); return builder.create(); } }
Показать диалог
Чтобы отобразить диалоговое окно, создайте экземпляр DialogFragment и вызовите show() , передав в FragmentManager и имя тега для фрагмента диалогового окна.
Получить FragmentManager можно, вызвав getSupportFragmentManager() из FragmentActivity или метод getParentFragmentManager() из Fragment . Пример приведен ниже:
Котлин
fun confirmStartGame() { val newFragment = StartGameDialogFragment() newFragment.show(supportFragmentManager, "game") }
Java
public void confirmStartGame() { DialogFragment newFragment = new StartGameDialogFragment(); newFragment.show(getSupportFragmentManager(), "game"); }
Второй аргумент, "game" , — это уникальное имя тега, которое система использует для сохранения и восстановления состояния фрагмента при необходимости. Тег также позволяет получить доступ к фрагменту, вызвав метод findFragmentByTag() .
Отобразить диалоговое окно в полноэкранном режиме или в виде встроенного фрагмента.
Возможно, вам потребуется, чтобы элемент вашего пользовательского интерфейса в одних ситуациях отображался как диалоговое окно, а в других — как полноэкранный или встроенный фрагмент. Также может потребоваться, чтобы его внешний вид менялся в зависимости от размера экрана устройства. Класс DialogFragment предоставляет гибкие возможности для достижения этой цели, поскольку он может выступать в качестве встраиваемого Fragment .
Однако в этом случае вы не можете использовать AlertDialog.Builder или другие объекты Dialog для создания диалогового окна. Если вы хотите, чтобы DialogFragment можно было встраивать, определите пользовательский интерфейс диалогового окна в макете, а затем загрузите этот макет в функции обратного вызова onCreateView() .
Вот пример DialogFragment , который может отображаться как диалоговое окно или как встраиваемый фрагмент, с использованием макета с именем purchase_items.xml :
Котлин
class CustomDialogFragment : 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 fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // Inflate the layout to use as a 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 fun onCreateDialog(savedInstanceState: Bundle): Dialog { // The only reason you might override this method when using // onCreateView() is to modify the dialog characteristics. For example, // the dialog includes a title by default, but your custom layout might // not need it. Here, you can remove the dialog title, but you must // call the superclass to get the Dialog. val dialog = super.onCreateDialog(savedInstanceState) dialog.requestWindowFeature(Window.FEATURE_NO_TITLE) return dialog } }
Java
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 a 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 the dialog characteristics. For example, // the dialog includes a title by default, but your custom layout might // not need it. 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; } }
В следующем примере определяется, следует ли отображать фрагмент в виде диалогового окна или в полноэкранном режиме в зависимости от размера экрана:
Котлин
fun showDialog() { val fragmentManager = supportFragmentManager val newFragment = CustomDialogFragment() if (isLargeLayout) { // 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. val transaction = fragmentManager.beginTransaction() // For a polished look, 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() } }
Java
public void showDialog() { FragmentManager fragmentManager = getSupportFragmentManager(); CustomDialogFragment newFragment = new CustomDialogFragment(); if (isLargeLayout) { // 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 polished look, 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(); } }
Для получения дополнительной информации о выполнении фрагментных транзакций см. раздел «Фрагменты» .
В этом примере логическая переменная mIsLargeLayout указывает, должно ли текущее устройство использовать большой формат макета приложения и, следовательно, отображать этот фрагмент в виде диалогового окна, а не в полноэкранном режиме. Лучший способ задать такую логическую переменную — объявить логическое значение ресурса с альтернативным значением ресурса для разных размеров экрана. Например, вот два варианта логического ресурса для разных размеров экрана:
res/values/bools.xml
<!-- Default boolean values --> <resources> <bool name="large_layout">false</bool> </resources>
res/values-large/bools.xml
<!-- Large screen boolean values --> <resources> <bool name="large_layout">true</bool> </resources>
Затем вы можете инициализировать значение mIsLargeLayout в методе onCreate() активности, как показано в следующем примере:
Котлин
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) isLargeLayout = resources.getBoolean(R.bool.large_layout) }
Java
boolean isLargeLayout; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); isLargeLayout = getResources().getBoolean(R.bool.large_layout); }
Отображение действия в виде диалога на больших экранах.
Вместо того чтобы отображать диалоговое окно в полноэкранном режиме на маленьких экранах, вы можете добиться того же результата, отображая Activity в виде диалогового окна на больших экранах. Выбор подхода зависит от дизайна вашего приложения, но отображение Activity в виде диалогового окна часто полезно, когда ваше приложение разработано для маленьких экранов, и вы хотите улучшить пользовательский опыт на планшетах, отображая кратковременное Activity в виде диалогового окна.
Чтобы отображать активность в виде диалога только на больших экранах, примените тему Theme.Holo.DialogWhenLarge к элементу манифеста <activity> :
<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" >
Для получения дополнительной информации о том, как оформлять ваши мероприятия с помощью тем, см. раздел «Стили и темы» .
Закрыть диалог
Когда пользователь нажимает кнопку действия, созданную с помощью AlertDialog.Builder , система автоматически закрывает диалоговое окно.
Система также закрывает диалоговое окно, когда пользователь нажимает на элемент в списке диалоговых окон, за исключением случаев, когда список содержит переключатели или флажки. В противном случае вы можете закрыть диалоговое окно вручную, вызвав dismiss() для вашего DialogFragment .
Если вам необходимо выполнить определенные действия после закрытия диалогового окна, вы можете реализовать метод onDismiss() в вашем DialogFragment .
Вы также можете отменить диалоговое окно. Это специальное событие, указывающее на то, что пользователь покидает диалоговое окно, не завершив задачу. Это происходит, если пользователь нажимает кнопку «Назад», касается экрана за пределами области диалогового окна или если вы явно вызываете метод cancel() для Dialog , например, в ответ на кнопку «Отмена» в диалоговом окне.
Как показано в предыдущем примере, вы можете отреагировать на событие отмены, реализовав onCancel() в вашем классе DialogFragment .
