web-dev-qa-db-fra.com

Android AlertDialog avec texte changeant dynamiquement à chaque demande

Je souhaite afficher un AlertDialog avec une option susceptible de changer à chaque demande. Ainsi, par exemple, à un moment donné, je souhaite afficher l'option "Ajouter aux contacts", alors qu'une autre fois, elle devrait être "Supprimer des contacts".

Mon code fonctionne la première fois. Cependant, Android semble mettre en cache le AlertDialog afin que onCreateDialog ne soit pas exécuté la prochaine fois. Par conséquent, l'option ne change plus. Puis-je empêcher cette mise en cache ou existe-t-il simplement un autre moyen de modifier l'option?

Je travaille avec le SDK 1.5 mais en utilisant 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();
}
23
Ulrich Scheller

Vous pouvez également utiliser la fonction removeDialog (int) de l'activité. Lorsqu'une boîte de dialogue est fermée, l'activité enregistre généralement l'état de la boîte de dialogue (pour des raisons de performances, j'imagine). L'appel removeDialog (int) dans la boîte de dialogue force l'activité à décharger toutes les références de la boîte de dialogue et la supprime de l'écran si elle est affichée.

Créer des dialogues
Activité # removeDialog (int)

19
Andrew Burgess

Jetez un coup d'œil à la méthode onPrepareDialog qui sera appelée avant l'affichage de la boîte de dialogue. Vous pouvez modifier les valeurs requises en fonction du type de demande.

Exemple avec sélecteur de date

@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;
  }
}
33
JaanusSiim

Voici un dup de cette question: Android: impossible de modifier le texte affiché dans AlertDialog

Vous pouvez également le faire de la manière suivante: http://andmobidev.blogspot.com/2010/03/modifying-alert-dialogs-list-items.html

Ne semble-t-il pas ralentir l'affichage du menu Longpress cependant ...

4
kenyee

Je pense avoir un correctif pour le comportement incohérent mentionné ci-dessus. Lors de la création initiale de la boîte de dialogue (lorsqu'il s'agit encore d'un AlertDialog.Builder), vous devez définir le message sur un état initial (non nul) ou onPrepareDialog ne l'écrase PAS avec la valeur souhaitée. Ainsi, lorsque vous créez la boîte de dialogue, procédez comme ceci pour que le message ait toujours une valeur non nulle. J'ai lutté avec cela pendant des jours et j'ai trouvé cette solution par accident:

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

if ( message == null ) {
    resultAlert.setMessage("");
} else {
    resultAlert.setMessage(message);
}
4
Jerry Destremps

Je comprends les raisons de performance pour utiliser les boîtes de dialogue de gestion d'activité, mais recommande de ne pas les utiliser, sauf dans des cas simples. Les raisons en sont:

  1. L'argument Bundle n'a été ajouté qu'à l'API niveau 8 et ne peut donc pas être adopté pour des raisons de compatibilité ascendante. Cela signifie effectivement que 'onPrepareDialog' doit s'appuyer sur des variables non locales pour les différences d'état;

  2. La pratique indique un comportement faible et incohérent en réponse à toute modification apportée au dialogue dans le corps de 'onPrepareDialog'.

Aucune de ces difficultés ne se pose si les dialogues sont sous-classés et créés selon les besoins. 'setOwnerActivity' peut être appelé si nécessaire. 

1
user527897

Lorsque vous avez une boîte de dialogue personnalisée, vous pouvez modifier des éléments personnalisés à l'aide de dialog.getWindow (). FindViewById (...)

Cet exemple enregistre le dernier texte affiché et l'affiche à nouveau lors de l'affichage de la boîte de dialogue.

// 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 personnalisé du dialogue:

<?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
BubbaGum