Диалоговые окна в Android. Часть 1

от автора

Добрый день/вечер/утро, уважаемые хабравчане и Вы, %username%!
Я занимаюсь разработкой приложений для Android, обожаю эту операционную систему и хочу поделиться своим опытом использования в своих проектах диалоговых окон. В первую очередь эта статья записка очень пригодится начинающим в области разработки для Android.
Также для новичков в этой отрасли рекомендую сперва прочитать вот этот пост уважаемого Hoorsh.
А теперь приступим к рассмотрению данного вопроса (у которого есть несколько подводных камней) под катом.

Dialog

Dialog — это класс, принадлежащий Android SDK и помогающий нам, простым смертным программистам, работать с диалоговыми окнами в Android. Класс Dialog имеет 4 подкласса:

  • AlertDialog: это диалоговое окно для различных сообщений приложения, например «Вы хотите купить мое приложение?» или что то в этом роде. AlertDialog поддерживает три кнопки — утвердительную (OK), отрицательную (Cancel) и нейтральную (Later).
  • ProgressDialog: это диалоговое окно для отображения выполнения различных процессов, загрузки, например.
  • DatePickerDialog: диалоговое окно предлагает пользователю выбрать дату.
  • TimePickerDialog: диалоговое окно предлагает пользователю выбрать время

На первом из этого списка, AlertDialog мы и остановимся подробнее.

AlertDialog

Чтобы создать диалоговое окно AlertDialog нам в помощь потребуется экземпляр класса Builder:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
Теперь, когда у нас есть builder, мы можем «строить» свое собственное диалоговое окно. В параметры диалогового окна Вы можете написать множество различных параметров, но основными являются эти:

  • setTitle(int resID) — задает заголовок диалогового окна, принимает в качестве аргументов ссылку на ресурс или строку.
  • setMessage(int resID) — задает сообщение в диалоговом окне, также принимает ссылку на ресурс или строку.
  • setPositiveButton(int textID, DialogInterface.OnClickListener listener) — устанавливает на Вашем диалоговом окне утвердительную кнопку с текстом ресурса textID и слушателем listener. Методы setNegativeButton и setNeutralButton идентичны, с разницей в назначении кнопок.

Пример создания AlertDialog:

AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(R.string.dialog_about_title); builder.setMessage(R.string.dialog_about_message); builder.setCancelable(true); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { // Кнопка ОК 	@Override 	public void onClick(DialogInterface dialog, int which) { 		dialog.dismiss(); // Отпускает диалоговое окно					 	} }); AlertDialog dialog = builder.create(); 

В этом примере я использовал setCancelable(true) — это разрешает пользователю закрывать диалоговое окно с помощью хардварной кнопки Back. Еще я создал слушателя для утвердительной кнопки и использовал метод create(). Метод create() возвращает готовое диалоговое окно с вашими параметрами как экземпляр класса AlertDialog.
Вот мы и создали диалоговое окно! Следующая задача — показать его пользователю. Вот тут есть несколько вариантов:

  • showDialog(AlertDialog dialog) — самый простой способ показать диалоговое окно, но начиная с версии 3.0 разработчики Android не рекомендуют пользоваться этим методом, и в результате вы получите предупреждение, которое можно обойти только @SurpressWarning, что есть не совсем хорошо.
  • AlertDialog dialog.show() — альтернативный способ показать окно, для этого в экземпляре dialog должен лежать результат метода Builder.create().

Второй метод нам подходит больше, но писать в основной активности кучу различных Buider и AlertDialog портит читабельность кода. Поэтому целесообразней вынести создание и обработку диалоговых окон в новый класс, например:

public class DialogScreen { 	 	public static final int IDD_ABOUT = 1; // Идентификаторы диалоговых окон 	public static final int IDD_SETTINGS = 2; 	public static final int IDD_RATE = 3; 	 	public static AlertDialog getDialog(Activity activity, int ID) { 		AlertDialog.Builder builder = new AlertDialog.Builder(activity);  		switch(ID) { 		case IDD_ABOUT: // Диалоговое окно About 			builder.setTitle(R.string.dialog_about_title); 			builder.setMessage(R.string.dialog_about_message); 			builder.setCancelable(true); 			builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { // Кнопка ОК 				@Override 				public void onClick(DialogInterface dialog, int which) { 					dialog.dismiss(); // Отпускает диалоговое окно					 				} 			}); 			return builder.create(); 		case IDD_RATE: // Диалоговое окно Rate the app 			builder.setTitle(R.string.dialog_rate_title); 			builder.setMessage(R.string.dialog_rate_message); 			builder.setCancelable(true); 			builder.setPositiveButton(R.string.dialog_rate_ok, new DialogInterface.OnClickListener() { // Переход на оценку приложения 				@Override 				public void onClick(DialogInterface dialog, int which) { 					// Переход	 					dialog.dismiss(); 				} 			}); 			builder.setNeutralButton(R.string.dialog_rate_cancel, new DialogInterface.OnClickListener() { // Оценить приложение потом 				@Override 				public void onClick(DialogInterface dialog, int which) { 					dialog.dismiss(); // Отпускает диалоговое окно 				} 			}); 			builder.setNegativeButton(R.string.dialog_rate_buy, new DialogInterface.OnClickListener() { // Переход на покупку AdFree версии 				@Override 				public void onClick(DialogInterface dialog, int which) { 					// Переход		 					dialog.dismiss(); 				} 			}); 			return builder.create(); 		case IDD_SETTINGS: // Диалог настроек 			View view = activity.getLayoutInflater().inflate(R.layout.settings, null); // Получаем layout по его ID 			builder.setView(view); 			builder.setTitle(R.string.dialog_settings_title); 			builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { // Кнопка ОК                 public void onClick(DialogInterface dialog, int whichButton) {                     MainActivity.doSaveSettings(); // Переход в сохранение настроек MainActivity                     dialog.dismiss();                 }             }); 			builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { // Кнопка Отмена  				public void onClick(DialogInterface dialog, int which) { 					dialog.dismiss(); 				} 			}); 			builder.setCancelable(true); 			return builder.create(); 		default: 			return null; 		}		 	} }

Единственная заметка по поводу этого кода будет про использования метода setView(View view) в диалоге IDD_SETTINGS. У AlertDialog как и у всех остальных диалоговых окон есть одна приятная особенность — им можно задавать собственные Layout, что позволяет полностью видоизменять диалоговые окна и их содержимое. Здесь есть один подводный камень: обработку элементов этого Layout вы должны будете производить именно в той Activity, где вызываете это диалоговое окно. Например я показываю диалоговое окно IDD_SETTINGS в MainActivity с Layout по имени settings:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent" >      <SeekBar         android:id="@+id/seekVol"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignParentLeft="true"         android:layout_below="@+id/seekSense"         android:layout_marginTop="42dp" />      <TextView         android:id="@+id/textVol"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignParentLeft="true"         android:layout_below="@+id/seekSense"         android:layout_marginTop="20dp"         android:text="@string/dialog_settings_vol"         android:textAppearance="?android:attr/textAppearanceMedium" />      <TextView         android:id="@+id/textSense"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_alignParentLeft="true"         android:layout_alignParentTop="true"         android:text="@string/dialog_settings_sense"         android:textAppearance="?android:attr/textAppearanceMedium" />      <SeekBar         android:id="@+id/seekSense"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignParentLeft="true"         android:layout_below="@+id/textSense" />  </RelativeLayout>

Соответственно я загружаю это окно в MainActivity:

		AlertDialog dialog = DialogScreen.getDialog(this, DialogScreen.IDD_SETTINGS); 		dialog.show(); 			initSettings(dialog); 		}

Метод initSettings класса MainActivity в данном случае будет выглядеть так:

		// Определяем SeekBar и привязываем к нему дельты настроек 		SeekBar sb_sense = (SeekBar)dialog.findViewById(R.id.seekSense); 		SeekBar sb_vol = (SeekBar)dialog.findViewById(R.id.seekVol);			 		// Задаем этим SeekBar текущие значения настроек 		sb_sense.setProgress(sense); 		sb_vol.setProgress(volume);

Ну а дальше обрабатываете свои объекты как вам угодно.

Небольшой итог

1) Для большинства целей диалоговых окон подходит AlertDialog
2) AlertDialog может принимать вид layout с любыми объектами
3) Гораздо лучше использовать для диалоговых окон отдельный класс и пользоваться AlertDialog.show()
4) Обработка объектов кастомного layout производится в активности, вызвавшей диалог

В следующей части этой статьи пойдет речь о DialogFragment, который был включен в Android SDK начиная с 3.0 Honeycomb. Надеюсь эта статья поможет новичкам и не очень в своих квестах по завоеванию Google Play.

P.S.

Это моя первая статья для хабра, поэтому принимаю любую конструктивную критику. Заранее спасибо.

ссылка на оригинал статьи http://habrahabr.ru/post/166469/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *