Boîtes de dialogue

Essayer Compose
Jetpack Compose est le kit d'outils d'UI recommandé pour Android. Découvrez comment ajouter des composants dans Compose.

Une boîte de dialogue est une petite fenêtre qui invite l'utilisateur à prendre une décision ou à saisir des informations supplémentaires. Une boîte de dialogue ne remplit pas l'écran et est normalement utilisée pour les événements modaux qui nécessitent une action de l'utilisateur avant de pouvoir continuer.

Image montrant une boîte de dialogue de base
Figure 1. Boîte de dialogue de base.

La classe Dialog est la classe de base pour les boîtes de dialogue, mais n'instanciez pas Dialog directement. Optez plutôt pour l'une des sous-classes suivantes :

AlertDialog
Boîte de dialogue pouvant afficher un titre, jusqu'à trois boutons, une liste d'éléments sélectionnables ou une mise en page personnalisée.
DatePickerDialog ou TimePickerDialog
Boîte de dialogue avec une UI prédéfinie qui permet à l'utilisateur de sélectionner une date ou une heure.

Ces classes définissent le style et la structure de votre boîte de dialogue. Vous avez également besoin d'un DialogFragment comme conteneur pour votre boîte de dialogue. La classe DialogFragment fournit tous les contrôles dont vous avez besoin pour créer votre boîte de dialogue et gérer son apparence, au lieu d'appeler des méthodes sur l'objet Dialog.

L'utilisation de DialogFragment pour gérer la boîte de dialogue permet de gérer correctement les événements de cycle de vie, par exemple lorsque l'utilisateur appuie sur le bouton "Retour" ou fait pivoter l'écran. La classe DialogFragment vous permet également de réutiliser l'UI de la boîte de dialogue en tant que composant intégrable dans une UI plus grande, comme un Fragment traditionnel. Par exemple, lorsque vous souhaitez que l'UI de la boîte de dialogue s'affiche différemment sur les grands et les petits écrans.

Les sections suivantes de ce document décrivent comment utiliser un DialogFragment en combinaison avec un objet AlertDialog. Si vous souhaitez créer un sélecteur de date ou d'heure, consultez Ajouter des sélecteurs à votre application.

Créer un fragment de boîte de dialogue

Vous pouvez créer une grande variété de conceptions de boîtes de dialogue, y compris des mises en page personnalisées et celles décrites dans Boîtes de dialogue Material Design, en étendant DialogFragment et en créant un AlertDialog dans la méthode de rappel onCreateDialog().

Voici un exemple de AlertDialog de base géré dans un DialogFragment :

Kotlin

class StartGameDialogFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity?.let {
            // Use the Builder class for convenient dialog construction.
            val builder = AlertDialog.Builder(it)
            builder.setMessage("Start game")
                .setPositiveButton("Start") { dialog, id ->
                    // START THE GAME!
                }
                .setNegativeButton("Cancel") { dialog, id ->
                    // User cancelled the dialog.
                }
            // Create the AlertDialog object and return it.
            builder.create()
        } ?: throw IllegalStateException("Activity cannot be null")
    }
}

class OldXmlActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_old_xml)

        StartGameDialogFragment().show(supportFragmentManager, "GAME_DIALOG")
    }
}

Java

public class StartGameDialogFragment extends DialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction.
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_start_game)
               .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // START THE GAME!
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // User cancels the dialog.
                   }
               });
        // Create the AlertDialog object and return it.
        return builder.create();
    }
}
// ...

StartGameDialogFragment().show(supportFragmentManager, "GAME_DIALOG");

Lorsque vous créez une instance de cette classe et appelez show() sur cet objet, la boîte de dialogue s'affiche comme illustré dans la figure suivante.

Image montrant une boîte de dialogue de base avec deux boutons d'action
Figure 2 : Boîte de dialogue avec un message et deux boutons d'action.

La section suivante fournit plus de détails sur l'utilisation des API AlertDialog.Builder pour créer la boîte de dialogue.

Selon la complexité de votre boîte de dialogue, vous pouvez implémenter diverses autres méthodes de rappel dans DialogFragment, y compris toutes les méthodes de cycle de vie de fragment de base.

Créer une boîte de dialogue d'alerte

La classe AlertDialog vous permet de créer différents types de boîtes de dialogue et est souvent la seule classe de boîte de dialogue dont vous avez besoin. Comme le montre la figure ci-dessous, une boîte de dialogue d'alerte comporte trois régions :

  • Titre : ce champ est facultatif et n'est utilisé que lorsque la zone de contenu est occupée par un message détaillé, une liste ou une mise en page personnalisée. Si vous devez transmettre un message ou poser une question simple, vous n'avez pas besoin de titre.
  • Zone de contenu : elle peut afficher un message, une liste ou une autre mise en page personnalisée.
  • Boutons d'action : une boîte de dialogue peut contenir jusqu'à trois boutons d'action.

La classe AlertDialog.Builder fournit des API qui vous permettent de créer un AlertDialog avec ces types de contenus, y compris une mise en page personnalisée.

Pour créer un AlertDialog :

Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setMessage("I am the message")
    .setTitle("I am the title")

val dialog: AlertDialog = builder.create()
dialog.show()

Java

// 1. Instantiate an AlertDialog.Builder with its constructor.
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

// 2. Chain together various setter methods to set the dialog characteristics.
builder.setMessage(R.string.dialog_message)
       .setTitle(R.string.dialog_title);

// 3. Get the AlertDialog.
AlertDialog dialog = builder.create();

L'extrait de code précédent génère la boîte de dialogue suivante :

Image montrant une boîte de dialogue avec un titre, une zone de contenu et deux boutons d'action.
Figure 3 : Mise en page d'une boîte de dialogue d'alerte de base.

Ajouter des boutons

Pour ajouter des boutons d'action comme ceux de la figure 2, appelez les méthodes setPositiveButton() et setNegativeButton() :

Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setMessage("I am the message")
    .setTitle("I am the title")
    .setPositiveButton("Positive") { dialog, which ->
        // Do something.
    }
    .setNegativeButton("Negative") { dialog, which ->
        // Do something else.
    }

val dialog: AlertDialog = builder.create()
dialog.show()

Java

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Add the buttons.
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // User taps OK button.
           }
       });
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // User cancels the dialog.
           }
       });
// Set other dialog properties.
...

// Create the AlertDialog.
AlertDialog dialog = builder.create();

Les méthodes set...Button() nécessitent un titre pour le bouton, fourni par une ressource de chaîne, et un DialogInterface.OnClickListener qui définit l'action à effectuer lorsque l'utilisateur appuie sur le bouton.

Vous pouvez ajouter trois boutons d'action :

  • Positif : utilisez cette option pour accepter et poursuivre l'action ("OK").
  • Négatif : utilisez cette option pour annuler l'action.
  • Neutre : utilisez cette option lorsque l'utilisateur ne souhaite peut-être pas poursuivre l'action, mais ne souhaite pas nécessairement l'annuler. Il s'affiche entre les boutons "Positif" et "Négatif". Par exemple, l'action peut être "Me le rappeler plus tard".

Vous ne pouvez ajouter qu'un seul type de bouton à un AlertDialog. Par exemple, vous ne pouvez pas avoir plusieurs boutons "positifs".

L'extrait de code précédent vous donne une boîte de dialogue d'alerte comme celle-ci :

Image montrant une boîte de dialogue d'alerte avec un titre, un message et deux boutons d'action.
Figure 4 : Boîte de dialogue d'alerte avec titre, message et deux boutons d'action.

Insérer une liste

Trois types de listes sont disponibles avec les API AlertDialog :

  • Liste à choix unique traditionnelle.
  • Liste persistante à choix unique (cases d'option).
  • Liste à choix multiples persistante (cases à cocher).

Pour créer une liste à choix unique comme celle de la figure 5, utilisez la méthode setItems() :


Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setTitle("I am the title")
    .setPositiveButton("Positive") { dialog, which ->
        // Do something.
    }
    .setNegativeButton("Negative") { dialog, which ->
        // Do something else.
    }
    .setItems(arrayOf("Item One", "Item Two", "Item Three")) { dialog, which ->
        // Do something on item tapped.
    }

val dialog: AlertDialog = builder.create()
dialog.show()

Java

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle(R.string.pick_color)
           .setItems(R.array.colors_array, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int which) {
               // The 'which' argument contains the index position of the selected item.
           }
    });
    return builder.create();
}

Cet extrait de code génère une boîte de dialogue semblable à celle-ci :

Image montrant une boîte de dialogue avec un titre et une liste.
Figure 5 : Boîte de dialogue avec un titre et une liste.

Étant donné que la liste apparaît dans la zone de contenu de la boîte de dialogue, celle-ci ne peut pas afficher à la fois un message et une liste. Définissez un titre pour la boîte de dialogue avec setTitle(). Pour spécifier les éléments de la liste, appelez setItems() en transmettant un tableau. Vous pouvez également spécifier une liste à l'aide de setAdapter(). Cela vous permet de sauvegarder la liste avec des données dynamiques (par exemple, à partir d'une base de données) à l'aide d'un ListAdapter.

Si vous sauvegardez votre liste avec un ListAdapter, utilisez toujours un Loader pour que le contenu se charge de manière asynchrone. Pour en savoir plus, consultez Créer des mises en page avec un adaptateur et Chargeurs.

Ajouter une liste persistante à choix multiples ou à choix unique

Pour ajouter une liste d'éléments à choix multiples (cases à cocher) ou à choix unique (boutons radio), utilisez respectivement les méthodes setMultiChoiceItems() ou setSingleChoiceItems().

Par exemple, voici comment créer une liste à choix multiples comme celle illustrée à la figure 6, qui enregistre les éléments sélectionnés dans un ArrayList :

Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setTitle("I am the title")
    .setPositiveButton("Positive") { dialog, which ->
        // Do something.
    }
    .setNegativeButton("Negative") { dialog, which ->
        // Do something else.
    }
    .setMultiChoiceItems(
        arrayOf("Item One", "Item Two", "Item Three"), null) { dialog, which, isChecked ->
        // Do something.
    }

val dialog: AlertDialog = builder.create()
dialog.show()

Java

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    selectedItems = new ArrayList();  // Where we track the selected items
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // Set the dialog title.
    builder.setTitle(R.string.pick_toppings)
    // Specify the list array, the items to be selected by default (null for
    // none), and the listener through which to receive callbacks when items
    // are selected.
           .setMultiChoiceItems(R.array.toppings, null,
                      new DialogInterface.OnMultiChoiceClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int which,
                       boolean isChecked) {
                   if (isChecked) {
                       // If the user checks the item, add it to the selected
                       // items.
                       selectedItems.add(which);
                   } else if (selectedItems.contains(which)) {
                       // If the item is already in the array, remove it.
                       selectedItems.remove(which);
                   }
               }
           })
    // Set the action buttons
           .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   // User taps OK, so save the selectedItems results
                   // somewhere or return them to the component that opens the
                   // dialog.
                   ...
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   ...
               }
           });

    return builder.create();
}
Image montrant une boîte de dialogue contenant une liste d'éléments à choix multiples.
Figure 6. Liste d'éléments à choix multiples.

Une boîte de dialogue d'alerte à choix unique peut être obtenue comme suit :

Kotlin

val builder: AlertDialog.Builder = AlertDialog.Builder(context)
builder
    .setTitle("I am the title")
    .setPositiveButton("Positive") { dialog, which ->
        // Do something.
    }
    .setNegativeButton("Negative") { dialog, which ->
        // Do something else.
    }
    .setSingleChoiceItems(
        arrayOf("Item One", "Item Two", "Item Three"), 0
    ) { dialog, which ->
        // Do something.
    }

val dialog: AlertDialog = builder.create()
dialog.show()

Java

        String[] choices = {"Item One", "Item Two", "Item Three"};
        
        AlertDialog.Builder builder = AlertDialog.Builder(context);
        builder
                .setTitle("I am the title")
                .setPositiveButton("Positive", (dialog, which) -> {

                })
                .setNegativeButton("Negative", (dialog, which) -> {

                })
                .setSingleChoiceItems(choices, 0, (dialog, which) -> {

                });

        AlertDialog dialog = builder.create();
        dialog.show();

Cela donne l'exemple suivant :

Image montrant une boîte de dialogue contenant une liste d'éléments à choix unique.
Figure 7. Liste d'éléments à choix unique.

Créer une mise en page personnalisée

Si vous souhaitez un mise en page personnalisée dans une boîte de dialogue, créez une mise en page et ajoutez-la à un AlertDialog en appelant setView() sur votre objet AlertDialog.Builder.

Image montrant une mise en page de boîte de dialogue personnalisée.
Figure 8 : Mise en page de boîte de dialogue personnalisée.

Par défaut, la mise en page personnalisée remplit la fenêtre de dialogue, mais vous pouvez toujours utiliser les méthodes AlertDialog.Builder pour ajouter des boutons et un titre.

Par exemple, voici le fichier de mise en page de la mise en page de boîte de dialogue personnalisée précédente :

res/layout/dialog_signin.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:src="@drawable/header_logo"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:scaleType="center"
        android:background="#FFFFBB33"
        android:contentDescription="@string/app_name" />
    <EditText
        android:id="@+id/username"
        android:inputType="textEmailAddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="4dp"
        android:hint="@string/username" />
    <EditText
        android:id="@+id/password"
        android:inputType="textPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="16dp"
        android:fontFamily="sans-serif"
        android:hint="@string/password"/>
</LinearLayout>

Pour développer la mise en page dans votre DialogFragment, obtenez un LayoutInflater avec getLayoutInflater() et appelez inflate(). Le premier paramètre est l'ID de ressource de mise en page, et le second paramètre est une vue parente pour la mise en page. Vous pouvez ensuite appeler setView() pour placer la mise en page dans la boîte de dialogue. Ce processus est illustré dans l'exemple suivant.

Kotlin

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return activity?.let {
        val builder = AlertDialog.Builder(it)
        // Get the layout inflater.
        val inflater = requireActivity().layoutInflater;

        // Inflate and set the layout for the dialog.
        // Pass null as the parent view because it's going in the dialog
        // layout.
        builder.setView(inflater.inflate(R.layout.dialog_signin, null))
                // Add action buttons.
                .setPositiveButton(R.string.signin,
                        DialogInterface.OnClickListener { dialog, id ->
                            // Sign in the user.
                        })
                .setNegativeButton(R.string.cancel,
                        DialogInterface.OnClickListener { dialog, id ->
                            getDialog().cancel()
                        })
        builder.create()
    } ?: throw IllegalStateException("Activity cannot be null")
}

Java

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // Get the layout inflater.
    LayoutInflater inflater = requireActivity().getLayoutInflater();

    // Inflate and set the layout for the dialog.
    // Pass null as the parent view because it's going in the dialog layout.
    builder.setView(inflater.inflate(R.layout.dialog_signin, null))
    // Add action buttons
           .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   // Sign in the user.
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   LoginDialogFragment.this.getDialog().cancel();
               }
           });
    return builder.create();
}

Si vous souhaitez un dialogue personnalisé, vous pouvez afficher un Activity en tant que boîte de dialogue au lieu d'utiliser les API Dialog. Créez une activité et définissez son thème sur Theme.Holo.Dialog dans l'élément de fichier manifeste <activity> :

<activity android:theme="@android:style/Theme.Holo.Dialog" >

L'activité s'affiche désormais dans une fenêtre de dialogue au lieu d'être en plein écran.

Transmettre les événements à l'hôte de la boîte de dialogue

Lorsque l'utilisateur appuie sur l'un des boutons d'action de la boîte de dialogue ou sélectionne un élément de sa liste, votre DialogFragment peut effectuer l'action nécessaire lui-même, mais vous souhaitez souvent transmettre l'événement à l'activité ou au fragment qui ouvre la boîte de dialogue. Pour ce faire, définissez une interface avec une méthode pour chaque type d'événement de clic. Implémentez ensuite cette interface dans le composant hôte qui reçoit les événements d'action de la boîte de dialogue.

Par exemple, voici un DialogFragment qui définit une interface par laquelle il renvoie les événements à l'activité hôte :

Kotlin

class NoticeDialogFragment : DialogFragment() {
    // Use this instance of the interface to deliver action events.
    internal lateinit var listener: NoticeDialogListener

    // The activity that creates an instance of this dialog fragment must
    // implement this interface to receive event callbacks. Each method passes
    // the DialogFragment in case the host needs to query it.
    interface NoticeDialogListener {
        fun onDialogPositiveClick(dialog: DialogFragment)
        fun onDialogNegativeClick(dialog: DialogFragment)
    }

    // Override the Fragment.onAttach() method to instantiate the
    // NoticeDialogListener.
    override fun onAttach(context: Context) {
        super.onAttach(context)
        // Verify that the host activity implements the callback interface.
        try {
            // Instantiate the NoticeDialogListener so you can send events to
            // the host.
            listener = context as NoticeDialogListener
        } catch (e: ClassCastException) {
            // The activity doesn't implement the interface. Throw exception.
            throw ClassCastException((context.toString() +
                    " must implement NoticeDialogListener"))
        }
    }
}

Java

public class NoticeDialogFragment extends DialogFragment {

    // The activity that creates an instance of this dialog fragment must
    // implement this interface to receive event callbacks. Each method passes
    // the DialogFragment in case the host needs to query it.
    public interface NoticeDialogListener {
        public void onDialogPositiveClick(DialogFragment dialog);
        public void onDialogNegativeClick(DialogFragment dialog);
    }

    // Use this instance of the interface to deliver action events.
    NoticeDialogListener listener;

    // Override the Fragment.onAttach() method to instantiate the
    // NoticeDialogListener.
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        // Verify that the host activity implements the callback interface.
        try {
            // Instantiate the NoticeDialogListener so you can send events to
            // the host.
            listener = (NoticeDialogListener) context;
        } catch (ClassCastException e) {
            // The activity doesn't implement the interface. Throw exception.
            throw new ClassCastException(activity.toString()
                    + " must implement NoticeDialogListener");
        }
    }
    ...
}

L'activité qui héberge la boîte de dialogue crée une instance de la boîte de dialogue avec le constructeur du fragment de boîte de dialogue et reçoit les événements de la boîte de dialogue via une implémentation de l'interface NoticeDialogListener :

Kotlin

class MainActivity : FragmentActivity(),
        NoticeDialogFragment.NoticeDialogListener {

    fun showNoticeDialog() {
        // Create an instance of the dialog fragment and show it.
        val dialog = NoticeDialogFragment()
        dialog.show(supportFragmentManager, "NoticeDialogFragment")
    }

    // The dialog fragment receives a reference to this Activity through the
    // Fragment.onAttach() callback, which it uses to call the following
    // methods defined by the NoticeDialogFragment.NoticeDialogListener
    // interface.
    override fun onDialogPositiveClick(dialog: DialogFragment) {
        // User taps the dialog's positive button.
    }

    override fun onDialogNegativeClick(dialog: DialogFragment) {
        // User taps the dialog's negative button.
    }
}

Java

public class MainActivity extends FragmentActivity
                          implements NoticeDialogFragment.NoticeDialogListener{
    ...
    public void showNoticeDialog() {
        // Create an instance of the dialog fragment and show it.
        DialogFragment dialog = new NoticeDialogFragment();
        dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
    }

    // The dialog fragment receives a reference to this Activity through the
    // Fragment.onAttach() callback, which it uses to call the following
    // methods defined by the NoticeDialogFragment.NoticeDialogListener
    // interface.
    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        // User taps the dialog's positive button.
        ...
    }

    @Override
    public void onDialogNegativeClick(DialogFragment dialog) {
        // User taps the dialog's negative button.
        ...
    }
}

Étant donné que l'activité hôte implémente NoticeDialogListener, qui est appliqué par la méthode de rappel onAttach() affichée dans l'exemple précédent, le fragment de boîte de dialogue peut utiliser les méthodes de rappel d'interface pour transmettre les événements de clic à l'activité :

Kotlin

    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        return activity?.let {
            // Build the dialog and set up the button click handlers.
            val builder = AlertDialog.Builder(it)

            builder.setMessage(R.string.dialog_start_game)
                    .setPositiveButton(R.string.start,
                            DialogInterface.OnClickListener { dialog, id ->
                                // Send the positive button event back to the
                                // host activity.
                                listener.onDialogPositiveClick(this)
                            })
                    .setNegativeButton(R.string.cancel,
                            DialogInterface.OnClickListener { dialog, id ->
                                // Send the negative button event back to the
                                // host activity.
                                listener.onDialogNegativeClick(this)
                            })

            builder.create()
        } ?: throw IllegalStateException("Activity cannot be null")
    }

Java

public class NoticeDialogFragment extends DialogFragment {
    ...
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Build the dialog and set up the button click handlers.
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_start_game)
               .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Send the positive button event back to the host activity.
                       listener.onDialogPositiveClick(NoticeDialogFragment.this);
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Send the negative button event back to the host activity.
                       listener.onDialogNegativeClick(NoticeDialogFragment.this);
                   }
               });
        return builder.create();
    }
}

Afficher une boîte de dialogue

Lorsque vous souhaitez afficher votre boîte de dialogue, créez une instance de votre DialogFragment et appelez show(), en transmettant le FragmentManager et un nom de tag pour le fragment de boîte de dialogue.

Vous pouvez obtenir FragmentManager en appelant getSupportFragmentManager() à partir de FragmentActivity ou en appelant getParentFragmentManager() à partir d'un Fragment. Voici un exemple :

Kotlin

fun confirmStartGame() {
    val newFragment = StartGameDialogFragment()
    newFragment.show(supportFragmentManager, "game")
}

Java

public void confirmStartGame() {
    DialogFragment newFragment = new StartGameDialogFragment();
    newFragment.show(getSupportFragmentManager(), "game");
}

Le deuxième argument, "game", est un nom de balise unique que le système utilise pour enregistrer et restaurer l'état du fragment si nécessaire. La balise vous permet également d'obtenir un handle vers le fragment en appelant findFragmentByTag().

Afficher une boîte de dialogue en plein écran ou en tant que fragment intégré

Il peut arriver que vous souhaitiez qu'une partie de votre conception d'UI apparaisse sous forme de boîte de dialogue dans certaines situations et sous forme de fragment en plein écran ou intégré dans d'autres. Vous pouvez également souhaiter qu'il s'affiche différemment en fonction de la taille de l'écran de l'appareil. La classe DialogFragment offre la flexibilité nécessaire pour y parvenir, car elle peut se comporter comme un Fragment intégrable.

Toutefois, vous ne pouvez pas utiliser AlertDialog.Builder ni d'autres objets Dialog pour créer la boîte de dialogue dans ce cas. Si vous souhaitez que DialogFragment soit intégrable, définissez l'UI de la boîte de dialogue dans une mise en page, puis chargez la mise en page dans le rappel onCreateView().

Voici un exemple de DialogFragment qui peut s'afficher sous forme de boîte de dialogue ou de fragment intégrable, à l'aide d'une mise en page nommée purchase_items.xml :

Kotlin

class CustomDialogFragment : DialogFragment() {

    // The system calls this to get the DialogFragment's layout, regardless of
    // whether it's being displayed as a dialog or an embedded fragment.
    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View {
        // Inflate the layout to use as a dialog or embedded fragment.
        return inflater.inflate(R.layout.purchase_items, container, false)
    }

    // The system calls this only when creating the layout in a dialog.
    override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
        // The only reason you might override this method when using
        // onCreateView() is to modify the dialog characteristics. For example,
        // the dialog includes a title by default, but your custom layout might
        // not need it. Here, you can remove the dialog title, but you must
        // call the superclass to get the Dialog.
        val dialog = super.onCreateDialog(savedInstanceState)
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        return dialog
    }
}

Java

public class CustomDialogFragment extends DialogFragment {
    // The system calls this to get the DialogFragment's layout, regardless of
    // whether it's being displayed as a dialog or an embedded fragment.
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout to use as a dialog or embedded fragment.
        return inflater.inflate(R.layout.purchase_items, container, false);
    }

    // The system calls this only when creating the layout in a dialog.
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // The only reason you might override this method when using
        // onCreateView() is to modify the dialog characteristics. For example,
        // the dialog includes a title by default, but your custom layout might
        // not need it. Here, you can remove the dialog title, but you must
        // call the superclass to get the Dialog.
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        return dialog;
    }
}

L'exemple suivant détermine s'il faut afficher le fragment sous forme de boîte de dialogue ou d'interface utilisateur en plein écran, en fonction de la taille de l'écran :

Kotlin

fun showDialog() {
    val fragmentManager = supportFragmentManager
    val newFragment = CustomDialogFragment()
    if (isLargeLayout) {
        // The device is using a large layout, so show the fragment as a
        // dialog.
        newFragment.show(fragmentManager, "dialog")
    } else {
        // The device is smaller, so show the fragment fullscreen.
        val transaction = fragmentManager.beginTransaction()
        // For a polished look, specify a transition animation.
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
        // To make it fullscreen, use the 'content' root view as the container
        // for the fragment, which is always the root view for the activity.
        transaction
                .add(android.R.id.content, newFragment)
                .addToBackStack(null)
                .commit()
    }
}

Java

public void showDialog() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    CustomDialogFragment newFragment = new CustomDialogFragment();

    if (isLargeLayout) {
        // The device is using a large layout, so show the fragment as a
        // dialog.
        newFragment.show(fragmentManager, "dialog");
    } else {
        // The device is smaller, so show the fragment fullscreen.
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        // For a polished look, specify a transition animation.
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        // To make it fullscreen, use the 'content' root view as the container
        // for the fragment, which is always the root view for the activity.
        transaction.add(android.R.id.content, newFragment)
                   .addToBackStack(null).commit();
    }
}

Pour en savoir plus sur l'exécution des transactions de fragment, consultez Fragments.

Dans cet exemple, le booléen mIsLargeLayout indique si l'appareil actuel doit utiliser la conception de mise en page volumineuse de l'application et donc afficher ce fragment sous forme de boîte de dialogue plutôt qu'en plein écran. La meilleure façon de définir ce type de booléen est de déclarer une valeur de ressource booléenne avec une valeur de ressource alternative pour différentes tailles d'écran. Par exemple, voici deux versions de la ressource booléenne pour différentes tailles d'écran :

res/values/bools.xml

<!-- Default boolean values -->
<resources>
    <bool name="large_layout">false</bool>
</resources>

res/values-large/bools.xml

<!-- Large screen boolean values -->
<resources>
    <bool name="large_layout">true</bool>
</resources>

Vous pouvez ensuite initialiser la valeur mIsLargeLayout pendant la méthode onCreate() de l'activité, comme indiqué dans l'exemple suivant :

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    isLargeLayout = resources.getBoolean(R.bool.large_layout)
}

Java

boolean isLargeLayout;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    isLargeLayout = getResources().getBoolean(R.bool.large_layout);
}

Afficher une activité sous forme de boîte de dialogue sur les grands écrans

Au lieu d'afficher une boîte de dialogue en tant qu'UI en plein écran sur les petits écrans, vous pouvez obtenir le même résultat en affichant un Activity en tant que boîte de dialogue sur les grands écrans. L'approche que vous choisissez dépend de la conception de votre application, mais il est souvent utile d'afficher une activité sous forme de boîte de dialogue lorsque votre application est conçue pour les petits écrans et que vous souhaitez améliorer l'expérience sur les tablettes en affichant une activité éphémère sous forme de boîte de dialogue.

Pour afficher une activité sous forme de boîte de dialogue uniquement sur les grands écrans, appliquez le thème Theme.Holo.DialogWhenLarge à l'élément de fichier manifeste <activity> :

<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" >

Pour en savoir plus sur la mise en forme de vos activités avec des thèmes, consultez Styles et thèmes.

Fermer une boîte de dialogue

Lorsque l'utilisateur appuie sur un bouton d'action créé avec un AlertDialog.Builder, le système ferme la boîte de dialogue pour vous.

Le système ferme également la boîte de dialogue lorsque l'utilisateur appuie sur un élément d'une liste de boîte de dialogue, sauf lorsque la liste utilise des boutons radio ou des cases à cocher. Sinon, vous pouvez fermer manuellement votre boîte de dialogue en appelant dismiss() sur votre DialogFragment.

Si vous devez effectuer certaines actions lorsque la boîte de dialogue disparaît, vous pouvez implémenter la méthode onDismiss() dans votre DialogFragment.

Vous pouvez également annuler une boîte de dialogue. Il s'agit d'un événement spécial qui indique que l'utilisateur quitte la boîte de dialogue sans terminer la tâche. Cela se produit si l'utilisateur appuie sur le bouton "Retour" ou sur l'écran en dehors de la zone de la boîte de dialogue, ou si vous appelez explicitement cancel() sur le Dialog, par exemple en réponse à un bouton "Annuler" dans la boîte de dialogue.

Comme le montre l'exemple précédent, vous pouvez répondre à l'événement d'annulation en implémentant onCancel() dans votre classe DialogFragment.