En Java / Swing, chaque méthode showXxxDialog de la classe JOptionPane crée une boite de dialogue modale demandant une action utilisateur. Elle est modale car l'utilisateur ne peut faire aucune action en dehors de celle-ci. Prenons l'exemple suivant :
if (reponse == JOptionPane.YES_NO_OPTION) {
// ... action si réponse = Oui
}
On constate que l'appel est synchrone, c'est à dire que la méthode retourne une valeur qui permet de traiter la réponse immédiatement.
Sous Android, les boites de dialogues sont aussi modales. Par contre, le traitement de la réponse doit être fait de manière asynchrone.
Il faut donc utiliser une stratégie de développement différente, basée sur les callback. Dans l'exemple d'une boite de dialogue Oui/Non, il faut une callback pour la réponse Oui et éventuellement une autre pour la réponse Non. Le code sous Android ressemble donc à ceci :
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage("Voulez-vous supprimer ce fichier ?");
builder.setPositiveButton("Oui", new DialogInterface.OnClickListener() { // définition de la callback pour la réponse Oui
@Override
public void onClick(DialogInterface dialog, int which) {
// ... action si réponse = Oui
}
});
builder.show(); // ne retourne pas le choix de l'utilisateur
// arrivé à la ligne suivante, l'utilisateur n'a peut être pas encore répondu à la question (car appel asynchrone)
Afin de rendre le code un peu plus clair, j'ai créé une classe abstraite appelée Command :
@Override
public final void onClick(DialogInterface dialog, int which) {
execute();
dialog.dismiss();
}
abstract public void execute();
}
J'ai également créé la méthode suivante :
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(context.getString(messageId));
builder.setPositiveButton("Oui", commandYes);
builder.show();
}
Je l'appelle comme ça :
int messageId = .....; // récupération de l'identifiant du message "Voulez-vous supprimer ce fichier ?"
Command yesCommand = new Command() {
public void execute() {
// ... action si réponse = Oui
}
};
displayYesNoDialog(activity, messageId, yesCommand);