Урок 61. Диалоги. AlertDialog.Метод onPrepareDialog
В этом уроке:
- используем метод подготовки диалога
Когда мы создаем диалог в методе onCreateDialog, Activity складывает его в кучу созданных диалогов. И когда надо отобразить, достает его и показывает. Т.е. метод onCreateDialog выполняется только один раз для диалога. И если вам надо перед отображением что-то изменить, надо использовать метод onPrepareDialog. Этот метод вызывается каждый раз перед показом диалога.
Напишем приложение, в нем будет AlertDialog, который будет показывать текущее время.
Создадим проект:
Project name: P0611_AlertDialogPrepare
Build Target: Android 2.3.3
Application name: AlertDialogPrepare
Package name: ru.startandroid.develop.p0611alertdialogprepare
Create Activity: MainActivity
На экране main.xml только кнопка:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"
android:onClick="onclick">
</Button>
</LinearLayout>
MainActivity.java:
package ru.startandroid.develop.p0611alertdialogprepare;
import java.sql.Date;
import java.text.SimpleDateFormat;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends Activity {
final static String LOG_TAG = "myLogs";
final int DIALOG = 1;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void onclick(View v) {
showDialog(DIALOG);
}
protected Dialog onCreateDialog(int id) {
Log.d(LOG_TAG, "onCreateDialog");
if (id == DIALOG) {
AlertDialog.Builder adb = new AlertDialog.Builder(this);
adb.setTitle("Текущее время");
adb.setMessage(sdf.format(new Date(System.currentTimeMillis())));
return adb.create();
}
return super.onCreateDialog(id);
}
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
Log.d(LOG_TAG, "onPrepareDialog");
if (id == DIALOG) {
((AlertDialog)dialog).setMessage(sdf.format(new Date(System.currentTimeMillis())));
}
}
}
SimpleDateFormat – это класс, позволяющий выводить дату-время в нужном формате. Задаем ему формат HH:mm:ss и он покажет время в классическом виде часы:минуты:секунды.
В onCreateDialog создаем диалог и устанавливаем заголовок и текст. Кнопки не добавляем, они не нужны. Диалог можно будет закрыть кнопкой Назад.
В onPrepareDialog мы на вход получаем ID вызываемого диалога и сам диалог (Dialog). Мы преобразуем его к AlertDialog и пишем в текст диалога текущее время.
В методах создания и подготовки диалога мы пишем лог, чтобы убедиться, что создание происходит один раз, а подготовка выполняется перед каждым показом.
Все сохраним и запустим приложение. Нажмем кнопку, появился диалог:
Показывает время. Смотрим лог:
onCreateDialog
onPrepareDialog
Выполнились оба метода – создание и подготовка.
Закроем диалог (но не программу) и вызовем снова
Время обновилось, а в логах добавилась запись.
onPrepareDialog
На этот раз Activity просто достало созданный ранее диалог и выполнило метод его подготовки.
Т.е. когда мы показываем диалог первый раз, он проходит через методы создания и подготовки. Далее мы его закрываем, но при этом объект не уничтожается, а Activity сохраняет его у себя. И когда мы снова хотим отобразить диалог, Activity достает его, прогоняет через метод подготовки и показывает.
В этом механизме есть небольшой изъян. Диалог, как и все экраны, состоит из набора View-компонентов. В зависимости от используемых при создании параметров диалог задает видимость этих View. Т.е. если вы при создании не задали, например, Message, то в созданном диалоге будет скрыта View (setVisibility(View.GONE)), которая отвечает за отображение текста Message. И если в методе подготовки диалога вы решите-таки Message указать, то диалог его просто не отобразит, т.к. структура задается при создании.
Я не нашел способ, как можно заставить диалог заново сформировать себя без удаления и создания заново. Если кто знает – пишите, добавлю в урок. А о том, как удалить диалог, чтобы при показе снова вызвался метод onCreateDialog, мы еще поговорим в следующих уроках.
На следующем уроке:
- формируем список в диалоге