web-dev-qa-db-fra.com

Comment rejeter correctement un DialogFragment?

Les docs disent ceci pour la méthode dismiss() de la classe Dialog:

Fermez cette boîte de dialogue en la supprimant de l'écran. Cette méthode peut être invoquée en toute sécurité de tout fil. Notez que vous ne devez pas remplacer cette méthode pour faire nettoyer lorsque la boîte de dialogue est fermée, implémentez plutôt cela dans onStop().

Dans mon code, tout ce que je fais est d'appeler getDialog().dismiss() pour le rejeter. Mais je ne fais rien d’autre ni même d’utiliser onStop(). Je demande donc exactement comment supprimer correctement une DialogFragment afin d'éviter toute fuite de mémoire, etc.

98
Andy

tl; dr: La manière correcte de fermer une DialogFragment consiste à utiliser dismiss()directement sur le DialogFragment.


Details: la documentation de DialogFragment states

Le contrôle de la boîte de dialogue (décider quand afficher, masquer, la fermer) doit être effectué via l'API ici, pas avec des appels directs sur la boîte de dialogue.

Ainsi, vous ne devriez pas utiliser getDialog().dismiss(), car cela invoquerait dismiss()dans la boîte de dialogue. Au lieu de cela, vous devez utiliser la méthode dismiss() du DialogFragment lui-même:

public void licencier ()

Rejeter le fragment et son dialogue. Si le fragment a été ajouté à la pile arrière, tous les états de pile arrière jusqu'à et y compris cette entrée seront affichés. Sinon, une nouvelle transaction sera validée pour supprimer le fragment.

Comme vous pouvez le constater, cela prend soin non seulement de fermer la boîte de dialogue, mais également de gérer les transactions de fragments impliquées dans le processus.

Vous devez uniquement utiliser onStop si vous avez explicitement créé des ressources nécessitant un nettoyage manuel (fermeture de fichiers, fermeture de curseurs, etc.). Même dans ce cas, je remplacerais onStop du DialogFragment plutôt que onStop du dialogue sous-jacent.

162
Heinzi

Je pense qu'une meilleure façon de fermer une DialogFragment est la suivante:

Fragment prev = getSupportFragmentManager().findFragmentByTag("fragment_dialog");
if (prev != null) {
    DialogFragment df = (DialogFragment) prev;
    df.dismiss();
}

De cette façon, vous n’avez pas à faire de référence à la DialogFragment et vous pouvez la fermer de partout.

61
Terel

J'ai donné un vote positif à la réponse de Terel. Je voulais juste poster ceci pour tous les utilisateurs de Kotlin:

supportFragmentManager.findFragmentByTag(TAG_DIALOG)?.let {
    (it as DialogFragment).dismiss()
}
2
JustinMorris

Pourquoi n'essayez-vous pas d'utiliser uniquement ce code:

dismiss();

Si vous voulez ignorer le fragment de dialogue par lui-même. Vous pouvez simplement mettre ce code dans le fragment de boîte de dialogue où vous souhaitez fermer la boîte de dialogue.

Par exemple:

button.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       dismiss();
   }
});

Cela fermera le récent fragment de dialogue affiché à l'écran.

J'espère que cela vous aidera.

2
Shiva Tiwari

Vous devriez vous renvoyer Dialog dans onPause() alors remplacez-le.

Aussi, avant de quitter, vous pouvez vérifier pour null et est affiché comme suit:

@Override
protected void onPause() {
    super.onPause();
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
    }
}
1
Venky

Version Kotlin de Terel répond

(fragmentManager.findFragmentByTag(TAG) as? DialogFragment)?.dismiss()
1
Phil

Appelez simplement licencier () du fragment que vous souhaitez supprimer.

imageView3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            dismiss();
        }
    });
0
VIVEK CHOUDHARY

Il y a des références aux documents officiels ( DialogFragment Reference ) dans d'autres réponses, mais aucune mention de l'exemple donné ici:

void showDialog() {
    mStackLevel++;

    // DialogFragment.show() will take care of adding the fragment
    // in a transaction.  We also want to remove any currently showing
    // dialog, so make our own transaction and take care of that here.
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    Fragment prev = getFragmentManager().findFragmentByTag("dialog");
    if (prev != null) {
        ft.remove(prev);
    }
    ft.addToBackStack(null);

    // Create and show the dialog.
    DialogFragment newFragment = MyDialogFragment.newInstance(mStackLevel);
    newFragment.show(ft, "dialog");
}

Cela supprime toute boîte de dialogue actuellement affichée, crée un nouveau DialogFragment avec un argument et l'affiche sous la forme d'un nouvel état dans la pile arrière. Lorsque la transaction est affichée, le DialogFragment actuel et son dialogue sont détruits et le précédent (le cas échéant) ré-affiché. Notez que dans ce cas, DialogFragment se chargera de faire apparaître la transaction du dialogue est rejetée séparément de celle-ci.

Pour mes besoins je l'ai changé en:

FragmentManager manager = getSupportFragmentManager();
Fragment prev = manager.findFragmentByTag(TAG);
if (prev != null) {
    manager.beginTransaction().remove(prev).commit();
}

MyDialogFragment fragment = new MyDialogFragment();
fragment.show(manager, TAG);
0
Maksim Ivanov