В этом уроке:

- используем метод подготовки диалога

 

 

Когда мы создаем диалог в методе 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, мы еще поговорим в следующих уроках.

 

На следующем уроке:

- формируем список в диалоге 


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня




Language

Автор сайта

Дмитрий Виноградов

Подробнее можно посмотреть или почитать.

Никакие другие люди не имеют к этому сайту никакого отношения и просто занимаются плагиатом.

Социальные сети

 

В канале я публикую ссылки на интересные и полезные статьи по Android

В чате можно обсудить вопросы и проблемы, возникающие при разработке



Группа ВКонтакте



Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal