Afficher les boîtes de dialogue avec DialogFragment

DialogFragment est une sous-classe de fragment spéciale conçue pour créer et héberger des boîtes de dialogue. Bien que vous n'ayez pas besoin d'héberger votre boîte de dialogue dans un fragment, FragmentManager gère l'état de la boîte de dialogue et la restaure automatiquement en cas de modification de la configuration.

Créer un DialogFragment

Pour créer un DialogFragment, créez une classe qui étend DialogFragment et supprimez onCreateDialog(), comme illustré dans l'exemple suivant.

Kotlin

class PurchaseConfirmationDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
            AlertDialog.Builder(requireContext())
                .setMessage(getString(R.string.order_confirmation))
                .setPositiveButton(getString(R.string.ok)) { _,_ -> }
                .create()

    companion object {
        const val TAG = "PurchaseConfirmationDialog"
    }
}

Java

public class PurchaseConfirmationDialogFragment extends DialogFragment {
   @NonNull
   @Override
   public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
       return new AlertDialog.Builder(requireContext())
               .setMessage(getString(R.string.order_confirmation))
               .setPositiveButton(getString(R.string.ok), (dialog, which) -> {} )
               .create();
   }

   public static String TAG = "PurchaseConfirmationDialog";
}

De la même manière que onCreateView() crée une racine View dans un fragment ordinaire, onCreateDialog() crée une Dialog à afficher dans le cadre de DialogFragment. DialogFragment gère l'affichage de la Dialog aux états appropriés dans le cycle de vie du fragment.

Comme pour onCreateView(), vous pouvez renvoyer n'importe quelle sous-classe de Dialog à partir de onCreateDialog(). Vous n'êtes pas limité à l'utilisation de AlertDialog.

Afficher le DialogFragment

Vous n'avez pas besoin de créer une FragmentTransaction manuellement pour afficher votre DialogFragment. Utilisez plutôt la méthode show() pour afficher votre boîte de dialogue. Vous pouvez transmettre une référence à FragmentManager et à String pour l'utiliser comme une balise de FragmentTransaction.

Lorsque vous créez un DialogFragment à partir d'un Fragment, utilisez le FragmentManager enfant du fragment afin que l'état soit correctement restauré une fois la configuration modifiée. Une balise non nulle vous permet d'utiliser findFragmentByTag() pour récupérer le DialogFragment ultérieurement.

Kotlin

// From another Fragment or Activity where you wish to show this
// PurchaseConfirmationDialogFragment.
PurchaseConfirmationDialogFragment().show(
     childFragmentManager, PurchaseConfirmationDialog.TAG)

Java

// From another Fragment or Activity where you wish to show this
// PurchaseConfirmationDialogFragment.
new PurchaseConfirmationDialogFragment().show(
       getChildFragmentManager(), PurchaseConfirmationDialog.TAG);

Pour avoir plus de contrôle sur la FragmentTransaction, vous pouvez utiliser la surcharge show() qui accepte un objet FragmentTransaction existant.

Cycle de vie d'un DialogFragment

Un DialogFragment suit le cycle de vie du fragment standard, avec quelques rappels de cycle de vie supplémentaires. Les plus courants sont les suivants :

  • onCreateDialog() : supprimez ce rappel afin de fournir une Dialog que le fragment doit gérer et afficher.
  • onDismiss() : remplacez ce rappel si vous devez exécuter une logique personnalisée lorsque votre Dialog est ignorée, par exemple pour libérer des ressources ou vous désabonner des ressources observables.
  • onCancel() : supprimez ce rappel si vous devez exécuter une logique personnalisée lorsque votre Dialog est annulée.

DialogFragment contient également des méthodes permettant d'ignorer ou de définir la possibilité d'annulation de votre DialogFragment :

  • dismiss() : permet d'ignorer le fragment et sa boîte de dialogue. Si le fragment a été ajouté à la pile "Retour", tous les états de la pile "Retour" jusqu'à cette entrée (incluse) sont supprimés. Sinon, une nouvelle transaction est validée pour supprimer le fragment.
  • setCancelable() : contrôle si la Dialog affichée peut être annulée. Utilisez cette méthode au lieu d'appeler directement Dialog.setCancelable(boolean).

Vous ne remplacez pas onCreateView() ni onViewCreated() lorsque vous utilisez DialogFragment avec une Dialog. Les boîtes de dialogue ne sont pas que des vues : elles ont leur propre fenêtre. Par conséquent, il ne suffit pas de remplacer onCreateView(). De plus, onViewCreated() n'est jamais appelé sur un DialogFragment personnalisé, sauf si vous avez remplacé onCreateView() et fourni une vue non nulle.

Utiliser des vues personnalisées

Vous pouvez créer un DialogFragment et afficher une boîte de dialogue en remplaçant onCreateView(). Vous pouvez lui attribuer un layoutId, comme avec un fragment classique, ou utiliser le constructeur DialogFragment.

L'élément View renvoyé par onCreateView() est automatiquement ajouté à la boîte de dialogue. Dans la plupart des cas, cela signifie que vous n'avez pas besoin de supprimer onCreateDialog(), car la vue est ajoutée à la boîte de dialogue qui est vide par défaut.

Certaines sous-classes de DialogFragment, telles que BottomSheetDialogFragment, intègrent votre affichage dans une boîte de dialogue stylisée sous la forme d'une bottom sheet.