OnCancelListener n'est pas appelée dans DialogFragment
J'ai un simple AlertDialog
qui affiche une liste de certains éléments et en cliquant sur l'un d'entre eux, l'élément cliqué est passé à l'enfermant Activity
. Je tiens également à effectuer certaines gestion par défaut lorsque l'utilisateur annule la boîte de dialogue (à l'aide de la bouton de retour) - plus précisément, je veux passer une chaîne vide à l'activité dans de tels cas.
Cependant, si je mets la boîte de dialogue dans un DialogFragment
(à partir de la package de compatibilité), le OnCancelListener
n'est pas appelé quand j'ai fermer la boîte de dialogue avec le bouton de retour. Ce que je fais mal?
public class SelectItemDialog extends DialogFragment {
public interface Callback {
void onItemSelected(String string);
}
private static final String ARG_ITEMS = "items";
private Callback callback;
public static SelectItemDialog fromItems(Collection<String> items) {
SelectItemDialog fragment = new SelectItemDialog();
fragment.setArguments(newArguments(items));
return fragment;
}
private static Bundle newArguments(Collection<String> items) {
Bundle arguments = new Bundle();
arguments.putStringArray(ARG_ITEMS, items.toArray(new String[items.size()]));
return arguments;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
callback = (Callback) activity;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final String[] items = getArguments().getStringArray(ARG_ITEMS);
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.dialog_select_email_title)
.setItems(items, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
callback.onItemSelected(items[which]);
}
})
.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
//this code is not executed
callback.onItemSelected("");
throw new RuntimeException("dialog cancelled");
}
})
.create();
}
}
Vous devez vous connecter pour publier un commentaire.
Il pourrait avoir à faire avec le fait qu'il n'y a pas d'appel explicite à
cancel()
à partir de votre code.Le OnCancelListener documentation dit:
Qui a probablement besoin d'un explicite
cancel()
appel.Soit positif/négatif bouton avec un
OnClickListener
que les appelsDialogInterface#cancel()
ou utiliser unOnDismissListener()
avec un supplément de vérifier pour voir si un élément de la liste a été cliqué.Aussi, pour écouter une pression de touche et annuler la boîte de dialogue, vous pouvez configurer un
OnKeyListener
, comme indiqué dans cette SORTE de réponseAussi, une fois que vous avez la boîte de Dialogue mis en place, il serait également une bonne idée d'utiliser
boîte de Dialogue#setCanceledOnTouchOutside()
dans le cas où l'utilisateur tape à l'extérieur de la boîte de Dialogue.Edit: Les dessous de la partie est le moyen le plus facile pour gérer les annuler des événements dans un DialogFragment.
Puisque vous êtes à l'aide d'un
DialogFragment
, cette classe est très pratique de la méthode,DialogFragment#onCancel()
qui est appelée lorsque leDialogFragment
est annulée. Faites votre logique là-dedans.DialogFragments sont plus complexes, avec un peu différents du cycle de vie que la normale boîtes de dialogue. Par conséquent, vérifiez d'abord la documentation si vous avez un certain
Dialog
basée sur l'approche que vous essayez de port pour unDialogFragment
, certaines méthodes existent qui permettent à votre nouvelle mise en œuvre de fonctionner correctement!OnCancelListener
d'être appelé lorsque la boîte de dialogue est fermée avec le bouton de retour.OnKeyListener
de regarder pour le retour de la touche.DialogFragment
, puis leOnCancelListener
est appelée fois sur le bouton de retour est pressé ou si l'utilisateur clique en dehors de la boîte de dialogue. Je ne comprends pas pourquoi leDialogFragment
change le comportement.onCancel()
. DialogFragments sont plus complexes que les boîtes de dialogue.DialogFragment#onCancel()
est exactement ce que je cherchais! Il semble que laDialogFragment
's méthodes remplacent les auditeurs de l'contenuesAlertDialog
. Cas similaire est également lesetCancelable()
méthode. Si vous intégrer dans votre réponse, je vais l'accepter.Si vous utilisez DialogFragment et voulez écouter de la touche retour, puis utiliser cette -
Remarque: DialogFragment propre la boîte de Dialogue.setOnCancelListener et de Dialogue.setOnDismissListener rappels. Vous ne devez pas définir vous-même.
Pour en savoir plus sur ces événements, remplacer onCancel(DialogInterface) et onDismiss(DialogInterface).
Et vous devez le supprimer .setOnCancelListener()
En fait, si vous voulez utiliser
DialogFragment
, vous pouvez ne jamais ajouterOnCancelListener
ouOnDismissListener
à elle, depuis la boîte de Dialogue Fragment possède des rappels de ces méthodes!Vous avez 3 options ici:
1 - rendez-vous régulier avec les boîtes de dialogue.
2 - définissez votre boîte de dialogue fragment de annulable(faux) et d'ajouter un bouton annuler de la boîte de dialogue.
3 - vérifiez @Nikhil Pingle réponse.
c'est à partir de la documentation de la boîte de Dialogue Fragment
Annuler Auditeur ou de Rejeter l'auditeur dans DialogFragment peut atteindre par onDismiss
DialogFragment.onDismiss(...)
appel. L'utilisateur n'a même pas de le voir.