Урок 65. Диалоги. AlertDialog. Кастомизация
В этом уроке:
- используем свои View для построения диалога
Кроме сообщения или списка мы можем помещать в диалог свои View-компоненты. Для этого доступно как основное тело диалога, так и заголовок. Для этого нам необходимо создать View и с помощью методов setCustomTitle или setView вставить этот View соответственно в заголовок или тело диалога. Я буду использовать только setView и работать с телом диалога. Использование метода setCustomTitle и работа с заголовком диалога полностью аналогична.
Нарисуем приложение, которое будет использовать свой View-компонент в теле диалога и рассмотрим, как можно модифицировать содержимое этого компонента. Будем добавлять и удалять TextView в теле диалога.
Создадим проект:
Project name: P0651_AlertDialogCustom
Build Target: Android 2.3.3
Application name: AlertDialogCustom
Package name: ru.startandroid.develop.p0651alertdialogcustom
Create Activity: MainActivity
В strings.xml пропишем тексты:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">AlertDialogCustom</string>
<string name="add">Добавить</string>
<string name="remove">Удалить</string>
</resources>
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:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/add"
android:onClick="onclick">
</Button>
<Button
android:id="@+id/btnRemove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/remove"
android:onClick="onclick">
</Button>
</LinearLayout>
dialog.xml – наше будущее кастом-тело диалога.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tvTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="">
</TextView>
<TextView
android:id="@+id/tvCount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="">
</TextView>
</LinearLayout>
В tvTime- будем отображать текущее время, а в tvCount – кол-во добавленных TextView.
MainActivity.java:
package ru.startandroid.develop.p0651alertdialogcustom;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
final int DIALOG = 1;
int btn;
LinearLayout view;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
TextView tvCount;
ArrayList<TextView> textViews;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textViews = new ArrayList<TextView>(10);
}
public void onclick(View v) {
btn = v.getId();
showDialog(DIALOG);
}
@Override
protected Dialog onCreateDialog(int id) {
AlertDialog.Builder adb = new AlertDialog.Builder(this);
adb.setTitle("Custom dialog");
// создаем view из dialog.xml
view = (LinearLayout) getLayoutInflater()
.inflate(R.layout.dialog, null);
// устанавливаем ее, как содержимое тела диалога
adb.setView(view);
// находим TexView для отображения кол-ва
tvCount = (TextView) view.findViewById(R.id.tvCount);
return adb.create();
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
if (id == DIALOG) {
// Находим TextView для отображения времени и показываем текущее
// время
TextView tvTime = (TextView) dialog.getWindow().findViewById(
R.id.tvTime);
tvTime.setText(sdf.format(new Date(System.currentTimeMillis())));
// если была нажата кнопка Добавить
if (btn == R.id.btnAdd) {
// создаем новое TextView, добавляем в диалог, указываем текст
TextView tv = new TextView(this);
view.addView(tv, new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
tv.setText("TextView " + (textViews.size() + 1));
// добавляем новое TextView в коллекцию
textViews.add(tv);
// иначе
} else {
// если коллекция созданных TextView непуста
if (textViews.size() > 0) {
// находим в коллекции последний TextView
TextView tv = textViews.get(textViews.size() - 1);
// удаляем из диалога
view.removeView(tv);
// удаляем из коллекции
textViews.remove(tv);
}
}
// обновляем счетчик
tvCount.setText("Кол-во TextView = " + textViews.size());
}
}
}
Рассмотрим код. В методе onCreate выполняем стандартные процедуры и создаем коллекцию textViews для хранения добавляемых TextView.
Метод onclick – обработчик нажатий на кнопки, сохраняет в btn идентификатор нажатой кнопки и показывает диалог.
В методе создания диалога onCreateDialog мы задаем текст заголовка диалога, создаем view из layout-файла dialog.xml и с помощью метода setView говорим диалогу, что надо использовать наше view в качестве тела диалога. И теперь, работая с view, мы будем формировать тело диалога. В только что созданном view сразу находим tvCount – для отображения кол-ва добавленных TextView.
Метод onPrepareDialog – здесь мы с помощью метода getWindow получаем доступ к View-компонентам диалога, находим среди них tvTime и показываем в нем время. Далее определяем, какая кнопка была нажата. Если кнопка добавления, то создаем TextView им помещаем его в view (который определили в методе onCreateDialog) и добавляем в коллекцию textViews. Таким образом TextView добавится в тело диалога. Если же хотим удалить TextView, то находим в коллекции последний добавленный и удаляем его из компонента view и из коллекции textViews. В конце обновляем счетчик кол-ва добавленных TextView в диалоге.
Обратите внимание, что я использую два разных способа для получения доступа к tvCount и tvTime. tvCount я нашел сразу после создания view в методе onCreateDialog. А в случае с tvTime я показываю, как найти View-компонент в диалоге без использования объекта view. Какой вам удобнее по ситуации, тот и используйте.
Все сохраним и запустим приложение. Нажмем кнопку Добавить
Появился диалог. Отображает время, кол-во добавленных TextView и собственно сами добавленные TextView.
Закрываем диалог кнопкой Назад, жмем еще раз добавить
Добавилось еще одно TextView.
Закрываем диалог, жмем кнопку Удалить.
Последнее TextView удалилось.
На следующем уроке:
- рассматриваем обработчики событий диалога
- программно закрываем и показываем диалог