Android AlertDialog с динамически меняющимся текстом на каждый запрос - PullRequest
24 голосов
/ 05 июня 2009

Я хочу показать AlertDialog с одной опцией, которая может меняться при каждом запросе. Так, например, в одно время я хочу показать опцию «добавить в контакты», а в другой раз «удалить из контактов».

Мой код работает с первого раза, однако Android, похоже, кеширует AlertDialog, так что onCreateDialog не выполняется в следующий раз Поэтому опция больше не меняется. Могу ли я предотвратить это кеширование или есть еще один способ изменить опцию?

Я работаю с SDK 1.5, но использую 1.1.

@Override
protected Dialog onCreateDialog(final int id) {
    ...
    String add_remove_contact = res.getString(R.string.profile_add_to_contacts);
    if (user.getContacts().contains(profileID)) {
        add_remove_contact = res.getString(R.string.profile_remove_from_contacts);
        // TODO: this string is not changed when contact status changes 
    }
    final CharSequence[] items = {res.getString(R.string.view_profile),
                                  res.getString(R.string.profile_send_message),
                                  add_remove_contact};
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    ...
    return builder.create();
}

Ответы [ 8 ]

33 голосов
/ 05 июня 2009

Посмотрите на onPrepareDialog метод, который будет вызван перед отображением диалогового окна. Там можно изменить необходимые значения в зависимости от типа запроса.

Пример со средством выбора даты

@Override
protected Dialog onCreateDialog(final int id) {
  switch (id) {
  case DIALOG_DATE_ID:
    final Calendar c = Calendar.getInstance();
    return new DatePickerDialog(this, this, c.get(Calendar.YEAR),
                                c.get(Calendar.MONTH), 
                                c.get(Calendar.DAY_OF_MONTH));
  default:
    return super.onCreateDialog(id);
  }
}

@Override
protected void onPrepareDialog(final int id, final Dialog dialog) {
  switch (id) {
  case DIALOG_DATE_ID:
    //update to current time
    final Calendar c = Calendar.getInstance();
    ((DatePickerDialog) dialog).updateDate(c.get(Calendar.YEAR), 
                                           c.get(Calendar.MONTH), 
                                           c.get(Calendar.DAY_OF_MONTH));
    break;
  }
}
19 голосов
/ 09 июня 2009

Вы также можете использовать функцию removeDialog (int) в Activity. Когда диалог закрывается, Activity в основном сохраняет состояние диалога (по причинам производительности, которые я мог бы себе представить). Вызов removeDialog (int) в диалоговом окне вынуждает действие выгружать все ссылки для диалогового окна и удаляет его с экрана, если оно отображается.

Создание диалогов
активность # removeDialog (INT)

4 голосов
/ 01 ноября 2011

Я думаю, что у меня есть исправление для противоречивого поведения, упомянутого выше. При первоначальном создании диалога (когда он все еще является AlertDialog.Builder), вы должны установить сообщение в начальное состояние (не нулевое), иначе onPrepareDialog НЕ перезапишет его с намеченным значением. Поэтому, когда вы создаете диалог, делайте что-то подобное, чтобы в сообщении всегда было ненулевое значение. Я боролся с этим в течение нескольких дней и нашел это решение случайно:

AlertDialog.Builder resultAlert = new AlertDialog.Builder(context);

if ( message == null ) {
    resultAlert.setMessage("");
} else {
    resultAlert.setMessage(message);
}
4 голосов
/ 06 июня 2010

Это дублирование этого вопроса: Android: невозможно изменить текст, появляется в AlertDialog

Вы также можете сделать это следующим образом: http://andmobidev.blogspot.com/2010/03/modifying-alert-dialogs-list-items.html

По-видимому, замедляет отображение меню длинного нажатия ...

1 голос
/ 03 декабря 2010

Я понимаю причины производительности для использования диалогов, управляемых активностью, но рекомендую, чтобы они не использовались, за исключением простых случаев. Причины этого:

  1. Аргумент Bundle был добавлен только в API уровня 8, поэтому его нельзя использовать для обратной совместимости. Это фактически означает, что 'onPrepareDialog' должен полагаться на нелокальные переменные для различий в состоянии;

  2. Практика указывает на плохое и непоследовательное поведение в ответ на любые изменения в диалоге, внесенные в тело onPrepareDialog.

Ни одна из этих трудностей не возникает, если диалоги делятся на подклассы и создаются по мере необходимости. setOwnerActivity может вызываться при необходимости.

0 голосов
/ 02 декабря 2016

Когда у вас есть настраиваемый диалог, вы можете изменить настраиваемые элементы с помощью dialog.getWindow (). FindViewById (...)

В этом примере сохраните последний показанный текст и снова отобразите его при следующем открытии диалогового окна.

// custom dialog
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.customized);

dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
    @Override
    public void onDismiss(DialogInterface dialogInterface) {
       EditText dialogText = (EditText)dialog.getWindow().findViewById(R.id.customText);
       savedText = dialogText.getText();
    }
});

dialog.show();
EditText dialogText = (EditText)dialog.getWindow().findViewById(R.id.customText);
dialogText.setText(savedText);

Пользовательский диалог xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<Button
    android:id="@+id/buttonOK"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="OK"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_marginBottom="16dp" />

<EditText
    android:id="@+id/customText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="19dp"
    android:hint="Message"
    android:ems="10"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true" />

0 голосов
/ 16 ноября 2011

И у меня есть идея, но не очень хорошая. * Это используется, когда пользователи не используют диалоговое окно достаточно часто! * Решение: во-первых, вы должны объявить переменную (тип int) и установите значение по умолчанию как 0.such как private int i=0; и прежде чем использовать методы Activity класса ShowDialog, увеличьте переменную int i и опишите значение i в качестве параметра в качестве метода showDialog. код может понравиться

private int i=0;

//before you show the dialog
this.i++;
this.showDialog(this.i);
0 голосов
/ 26 октября 2009

точно. для AlertDialog, который был создан с Builder.create(), onPrepareDialog() бесполезен. Builder является односторонним в том, что после создания диалогового окна вы не можете обновлять. я имею в виду, не могу свободно, я уверен, что вы могли бы получить ручку к представлению и сделать все это вручную, но это в первую очередь лишает смысла использование компоновщика.

единственное решение, которое я нашел, было вручную создать / показать / закрыть диалоговое окно вместо использования onCreateDialog(), showDialog() и т. Д. Я попытался вызвать removeDialog(), но это не помогло.

...