Ajouter des menus

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

Les menus sont un composant d'interface utilisateur courant dans de nombreux types d'applications. Pour offrir une expérience utilisateur familière et cohérente, utilisez les API Menu pour présenter les actions utilisateur et d'autres options dans vos activités.

Image montrant un exemple de menu à développer
Figure 1. Menu déclenché par un appui sur une icône, qui apparaît sous l'icône du menu à développer.

Ce document explique comment créer les trois types fondamentaux de menus ou de présentations d'actions sur toutes les versions d'Android:

Menu d'options et barre d'application
Le menu d'options est la collection principale d'éléments de menu pour une activité. C'est là que vous placez les actions ayant un impact global sur l'application, comme "Rechercher", "Rédiger un e-mail" ou "Paramètres".

Consultez la section Créer un menu d'options.

Menu contextuel et mode d'action contextuelle
Un menu contextuel est un menu flottant qui apparaît lorsque l'utilisateur appuie de manière prolongée sur un élément. Elle fournit des actions qui affectent le contenu ou le cadre de contexte sélectionné.

Le mode d'action contextuelle affiche les tâches qui affectent le contenu sélectionné dans une barre en haut de l'écran et permet à l'utilisateur de sélectionner plusieurs éléments.

Consultez la section Créer un menu contextuel.

Menu pop-up
Un menu pop-up affiche une liste verticale d'éléments ancré à la vue qui appelle le menu. Il est utile pour fournir un dépassement d'actions liées à un contenu spécifique ou pour fournir des options pour la deuxième partie d'une commande. Les actions d'un menu pop-up n'affectent pas directement le contenu correspondant. C'est à cela que servent les actions contextuelles. Il contient plutôt des actions étendues liées aux régions de contenu de votre activité.

Consultez la section Créer un menu pop-up.

Définir un menu en XML

Pour tous les types de menu, Android fournit un format XML standard pour définir les éléments de menu. Au lieu de créer un menu dans le code de votre activité, définissez un menu et tous ses éléments dans une ressource de menu XML. Vous pouvez ensuite gonfler la ressource de menu en la chargeant en tant qu'objet Menu dans votre activité ou fragment.

L'utilisation d'une ressource de menu est une bonne pratique pour les raisons suivantes:

  • Il est plus facile de visualiser la structure des menus en XML.
  • Elle sépare le contenu du menu du code comportemental de votre application.
  • Il vous permet de créer d'autres configurations de menu pour différentes versions de plate-forme, tailles d'écran et autres configurations en exploitant le framework des ressources d'application.

Pour définir un menu, créez un fichier XML dans le répertoire res/menu/ de votre projet, puis créez le menu avec les éléments suivants:

<menu>
Définit Menu, qui est un conteneur pour les éléments de menu. Un élément <menu> doit être le nœud racine du fichier. Il peut contenir un ou plusieurs éléments <item> et <group>.
<item>
Crée un MenuItem, qui représente un seul élément d'un menu. Cet élément peut contenir un élément <menu> imbriqué pour créer un sous-menu.
<group>
Conteneur invisible et facultatif pour les éléments <item>. Il vous permet de classer les éléments du menu afin qu'ils partagent des propriétés telles que l'état actif et la visibilité. Pour en savoir plus, consultez la section Créer un groupe de menus.

Voici un exemple de menu nommé game_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:icon="@drawable/ic_new_game"
          android:title="@string/new_game"
          app:showAsAction="ifRoom"/>
    <item android:id="@+id/help"
          android:icon="@drawable/ic_help"
          android:title="@string/help" />
</menu>

L'élément <item> accepte plusieurs attributs que vous pouvez utiliser pour définir l'apparence et le comportement d'un élément. Les éléments du menu précédent incluent les attributs suivants:

android:id
ID de ressource propre à l'élément, ce qui permet à l'application de reconnaître l'élément lorsque l'utilisateur le sélectionne.
android:icon
Référence à un drawable pouvant servir d'icône pour l'élément.
android:title
Référence à une chaîne à utiliser comme titre de l'élément.
android:showAsAction
Spécification indiquant quand et comment cet élément apparaît en tant que tâche dans la barre d'application.

Ce sont les attributs les plus importants que vous utilisez, mais il en existe beaucoup d'autres. Pour en savoir plus sur tous les attributs compatibles, consultez la documentation sur les ressources de menu.

Vous pouvez ajouter un sous-menu à un élément de n'importe quel menu en ajoutant un élément <menu> en tant qu'enfant d'un élément <item>. Les sous-menus sont utiles lorsque votre application dispose de nombreuses fonctions pouvant être organisées par sujets, comme les éléments de la barre de menu d'une application PC, tels que File (Fichier), Edit (Modifier) et View (Affichage). Consultez l'exemple suivant :

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/file"
          android:title="@string/file" >
        <!-- "file" submenu -->
        <menu>
            <item android:id="@+id/create_new"
                  android:title="@string/create_new" />
            <item android:id="@+id/open"
                  android:title="@string/open" />
        </menu>
    </item>
</menu>

Pour utiliser le menu dans votre activité, _générez_ la ressource de menu, en convertissant la ressource XML en objet programmable à l'aide de MenuInflater.inflate(). Les sections suivantes expliquent comment gonfler un menu pour chaque type de menu.

Menu d'options de création

Le menu d'options, comme celui illustré à la figure 1, vous permet d'inclure des actions et d'autres options en rapport avec le contexte d'activité actuel, telles que "Rechercher", "Rédiger un e-mail" et "Paramètres".

Image montrant la barre d&#39;application de l&#39;application Google Sheets
Figure 2 : Application Google Sheets affichant plusieurs boutons, y compris le bouton d'action à développer.

Vous pouvez déclarer des éléments pour le menu d'options à partir de votre sous-classe Activity ou Fragment. Si votre activité et vos fragments déclarent des éléments pour le menu d'options, ils sont combinés dans l'interface utilisateur. Les éléments de l'activité apparaissent en premier, suivis de ceux de chaque fragment, dans l'ordre dans lequel ils sont ajoutés à l'activité. Si nécessaire, vous pouvez réorganiser les éléments de menu avec l'attribut android:orderInCategory dans chaque <item> à déplacer.

Pour spécifier le menu d'options d'une activité, remplacez onCreateOptionsMenu(). Les fragments fournissent leur propre rappel onCreateOptionsMenu(). Avec cette méthode, vous pouvez gonfler votre ressource de menu, définie en XML, dans le Menu fourni dans le rappel. Ce processus est illustré dans l'exemple suivant :

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    val inflater: MenuInflater = menuInflater
    inflater.inflate(R.menu.game_menu, menu)
    return true
}

Java

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.game_menu, menu);
    return true;
}

Vous pouvez également ajouter des éléments de menu à l'aide de add() et récupérer des éléments avec findItem() pour réviser leurs propriétés avec les API MenuItem.

Gérer les événements de clic

Lorsque l'utilisateur sélectionne un élément dans le menu d'options, y compris des tâches dans la barre d'application, le système appelle la méthode onOptionsItemSelected() de votre activité. Cette méthode transmet l'élément MenuItem sélectionné. Vous pouvez identifier l'élément en appelant getItemId(), qui renvoie l'ID unique de l'élément de menu, défini par l'attribut android:id dans la ressource de menu ou avec un entier donné à la méthode add(). Vous pouvez mettre en correspondance cet ID avec des éléments de menu connus pour effectuer l'action appropriée.

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    // Handle item selection.
    return when (item.itemId) {
        R.id.new_game -> {
            newGame()
            true
        }
        R.id.help -> {
            showHelp()
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection.
    switch (item.getItemId()) {
        case R.id.new_game:
            newGame();
            return true;
        case R.id.help:
            showHelp();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Lorsque vous gérez correctement un élément de menu, renvoyez true. Si vous ne gérez pas l'élément de menu, appelez l'implémentation de super-classe de onOptionsItemSelected(). L'implémentation par défaut renvoie la valeur "false".

Si votre activité inclut des fragments, le système appelle d'abord onOptionsItemSelected() pour l'activité, puis pour chaque fragment dans l'ordre dans lequel les fragments sont ajoutés, jusqu'à ce que l'un renvoie true ou que tous les fragments soient appelés.

Modifier les éléments du menu au moment de l'exécution

Une fois que le système a appelé onCreateOptionsMenu(), il conserve une instance de Menu que vous renseignez et n'appelle plus onCreateOptionsMenu(), sauf si le menu n'est plus valide. Toutefois, n'utilisez onCreateOptionsMenu() que pour créer l'état de menu initial et non pour apporter des modifications pendant le cycle de vie de l'activité.

Si vous souhaitez modifier le menu d'options en fonction des événements qui se produisent au cours du cycle de vie de l'activité, vous pouvez utiliser la méthode onPrepareOptionsMenu(). Cette méthode vous transmet l'objet Menu tel qu'il existe actuellement afin que vous puissiez le modifier, par exemple en ajoutant, en supprimant ou en désactivant des éléments. Les fragments fournissent également un rappel onPrepareOptionsMenu().

Le menu d'options est considéré comme toujours ouvert lorsque les éléments de menu sont présentés dans la barre d'application. Lorsqu'un événement se produit et que vous souhaitez mettre à jour le menu, appelez invalidateOptionsMenu() pour demander au système d'appeler onPrepareOptionsMenu().

Créer un menu contextuel

Image montrant un menu contextuel flottant
Figure 3 : Menu contextuel flottant

Un menu contextuel propose des actions qui affectent un élément ou un cadre contextuel spécifique de l'interface utilisateur. Vous pouvez fournir un menu contextuel pour n'importe quelle vue, mais ils sont le plus souvent utilisés pour les éléments d'une RecylerView ou d'autres collections de vues dans lesquelles l'utilisateur peut effectuer des actions directes sur chaque élément.

Il existe deux façons de fournir des actions contextuelles:

  • Dans un menu contextuel flottant Un menu s'affiche sous la forme d'une liste flottante d'éléments de menu, semblable à une boîte de dialogue, lorsque l'utilisateur appuie de manière prolongée sur une vue qui déclare la prise en charge d'un menu contextuel. Les utilisateurs peuvent effectuer une action contextuelle sur un élément à la fois.
  • Vous êtes en mode d'action contextuelle. Ce mode est une implémentation système de ActionMode qui affiche une barre d'action contextuelle(CAB) en haut de l'écran, avec des tâches qui affectent le ou les éléments sélectionnés. Lorsque ce mode est actif, les utilisateurs peuvent effectuer une action sur plusieurs éléments à la fois, si votre application le permet.

Créer un menu contextuel flottant

Pour afficher un menu contextuel flottant, procédez comme suit:

  1. Enregistrez le View auquel le menu contextuel est associé en appelant registerForContextMenu() et en lui transmettant le View.

    Si votre activité utilise un RecyclerView et que vous souhaitez que chaque élément fournisse le même menu contextuel, enregistrez tous les éléments d'un menu contextuel en transmettant RecyclerView à registerForContextMenu().

  2. Implémentez la méthode onCreateContextMenu() dans votre fichier Activity ou Fragment.

    Lorsque la vue enregistrée reçoit un événement d'appui de manière prolongée, le système appelle votre méthode onCreateContextMenu(). C'est ici que vous définissez les éléments de menu, généralement en gonflant une ressource de menu, comme dans l'exemple suivant:

    Kotlin

        override fun onCreateContextMenu(menu: ContextMenu, v: View,
                                menuInfo: ContextMenu.ContextMenuInfo) {
            super.onCreateContextMenu(menu, v, menuInfo)
            val inflater: MenuInflater = menuInflater
            inflater.inflate(R.menu.context_menu, menu)
        }
        

    Java

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v,
                                        ContextMenuInfo menuInfo) {
            super.onCreateContextMenu(menu, v, menuInfo);
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.context_menu, menu);
        }
        

    MenuInflater vous permet de gonfler le menu contextuel à partir d'une ressource de menu. Les paramètres de la méthode de rappel incluent le View sélectionné par l'utilisateur et un objet ContextMenu.ContextMenuInfo qui fournit des informations supplémentaires sur l'élément sélectionné. Si votre activité comporte plusieurs vues qui fournissent chacune un menu contextuel différent, vous pouvez utiliser ces paramètres pour déterminer le menu contextuel à gonfler.

  3. Implémentez onContextItemSelected(), comme indiqué dans l'exemple suivant. Lorsque l'utilisateur sélectionne un élément de menu, le système appelle cette méthode pour que vous puissiez effectuer l'action appropriée.

    Kotlin

        override fun onContextItemSelected(item: MenuItem): Boolean {
            val info = item.menuInfo as AdapterView.AdapterContextMenuInfo
            return when (item.itemId) {
                R.id.edit -> {
                    editNote(info.id)
                    true
                }
                R.id.delete -> {
                    deleteNote(info.id)
                    true
                }
                else -> super.onContextItemSelected(item)
            }
        }
        

    Java

        @Override
        public boolean onContextItemSelected(MenuItem item) {
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
            switch (item.getItemId()) {
                case R.id.edit:
                    editNote(info.id);
                    return true;
                case R.id.delete:
                    deleteNote(info.id);
                    return true;
                default:
                    return super.onContextItemSelected(item);
            }
        }
        

    La méthode getItemId() interroge l'ID de l'élément de menu sélectionné, que vous attribuez à chaque élément de menu en XML à l'aide de l'attribut android:id, comme indiqué dans Définir un menu en XML.

    Lorsque vous gérez correctement un élément de menu, renvoyez true. Si vous ne gérez pas l'élément de menu, transmettez-le à l'implémentation de la super-classe. Si votre activité inclut des fragments, elle reçoit d'abord ce rappel. En appelant la super-classe lorsqu'elle n'est pas gérée, le système transmet l'événement à la méthode de rappel correspondante de chaque fragment, un par un, dans l'ordre dans lequel chaque fragment est ajouté, jusqu'à ce que true ou false soit renvoyé. Les implémentations par défaut pour Activity et android.app.Fragment renvoient false. Vous devez donc toujours appeler la super-classe lorsqu'elle n'est pas gérée.

Utiliser le mode d'action contextuelle

Le mode d'action contextuelle est une implémentation système de ActionMode qui cible les interactions de l'utilisateur vers l'exécution d'actions contextuelles. Lorsqu'un utilisateur active ce mode en sélectionnant un élément, une barre d'action contextuelle apparaît en haut de l'écran pour présenter les actions qu'il peut effectuer sur les éléments sélectionnés. Lorsque ce mode est activé, l'utilisateur peut sélectionner plusieurs éléments, si votre application le permet, et désélectionner des éléments et continuer à naviguer dans l'activité. Le mode d'action est désactivé et la barre d'action contextuelle disparaît lorsque l'utilisateur supprime tous les éléments, appuie sur le bouton "Retour" ou appuie sur l'action Done (Terminé) à gauche de la barre.

Pour les vues qui fournissent des actions contextuelles, vous appelez généralement le mode d'action contextuelle lorsque l'un de ces deux événements ou les deux se produisent:

  • L'utilisateur appuie de manière prolongée sur la vue.
  • L'utilisateur coche une case ou un composant d'interface utilisateur similaire dans la vue.

La manière dont votre application appelle le mode d'action contextuelle et définit le comportement de chaque action dépend de votre conception. Il existe deux modèles:

  • Pour les actions contextuelles sur des vues individuelles et arbitraires.
  • Pour les actions contextuelles par lot sur des groupes d'éléments dans une RecyclerView, ce qui permet à l'utilisateur de sélectionner plusieurs éléments et d'effectuer une action sur chacun d'eux.

Les sections suivantes décrivent la configuration requise pour chaque scénario.

Activer le mode d'action contextuelle pour des vues individuelles

Si vous souhaitez n'appeler le mode d'action contextuelle que lorsque l'utilisateur sélectionne des vues spécifiques, procédez comme suit:

  1. Implémentez l'interface ActionMode.Callback comme indiqué dans l'exemple suivant. Dans ses méthodes de rappel, vous pouvez spécifier les actions pour la barre d'action contextuelle, répondre aux événements de clic sur des tâches et gérer d'autres événements de cycle de vie pour le mode d'action.

    Kotlin

        private val actionModeCallback = object : ActionMode.Callback {
            // Called when the action mode is created. startActionMode() is called.
            override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
                // Inflate a menu resource providing context menu items.
                val inflater: MenuInflater = mode.menuInflater
                inflater.inflate(R.menu.context_menu, menu)
                return true
            }
    
            // Called each time the action mode is shown. Always called after
            // onCreateActionMode, and might be called multiple times if the mode
            // is invalidated.
            override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
                return false // Return false if nothing is done
            }
    
            // Called when the user selects a contextual menu item.
            override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
                return when (item.itemId) {
                    R.id.menu_share -> {
                        shareCurrentItem()
                        mode.finish() // Action picked, so close the CAB.
                        true
                    }
                    else -> false
                }
            }
    
            // Called when the user exits the action mode.
            override fun onDestroyActionMode(mode: ActionMode) {
                actionMode = null
            }
        }
        

    Java

        private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
    
            // Called when the action mode is created. startActionMode() is called.
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                // Inflate a menu resource providing context menu items.
                MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.context_menu, menu);
                return true;
            }
    
            // Called each time the action mode is shown. Always called after
            // onCreateActionMode, and might be called multiple times if the mode
            // is invalidated.
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false; // Return false if nothing is done.
            }
    
            // Called when the user selects a contextual menu item.
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
               switch (item.getItemId()) {
                    case R.id.menu_share:
                        shareCurrentItem();
                        mode.finish(); // Action picked, so close the CAB.
                        return true;
                    default:
                        return false;
                }
            }
    
            // Called when the user exits the action mode.
            @Override
            public void onDestroyActionMode(ActionMode mode) {
                actionMode = null;
            }
        };
        

    Ces rappels d'événement sont presque exactement identiques à ceux du menu d'options, sauf qu'ils transmettent également l'objet ActionMode associé à l'événement. Vous pouvez utiliser les API ActionMode pour apporter diverses modifications au CAB, telles que la révision du titre et du sous-titre avec setTitle() et setSubtitle(), ce qui est utile pour indiquer le nombre d'éléments sélectionnés.

    L'exemple précédent définit la variable actionMode sur null lorsque le mode d'action est détruit. À l'étape suivante, vous allez découvrir comment elle est initialisée et en quoi l'enregistrement de la variable de membre dans votre activité ou fragment peut être utile.

  2. Appelez startActionMode() lorsque vous souhaitez afficher la barre, par exemple lorsque l'utilisateur appuie de manière prolongée sur la vue.

    Kotlin

        someView.setOnLongClickListener { view ->
            // Called when the user performs a touch & hold on someView.
            when (actionMode) {
                null -> {
                    // Start the CAB using the ActionMode.Callback defined earlier.
                    actionMode = activity?.startActionMode(actionModeCallback)
                    view.isSelected = true
                    true
                }
                else -> false
            }
        }
        

    Java

        someView.setOnLongClickListener(new View.OnLongClickListener() {
            // Called when the user performs a touch & hold on someView.
            public boolean onLongClick(View view) {
                if (actionMode != null) {
                    return false;
                }
    
                // Start the CAB using the ActionMode.Callback defined earlier.
                actionMode = getActivity().startActionMode(actionModeCallback);
                view.setSelected(true);
                return true;
            }
        });
        

    Lorsque vous appelez startActionMode(), le système renvoie le ActionMode créé. En enregistrant cette valeur dans une variable de membre, vous pouvez modifier la barre d'action contextuelle en réponse à d'autres événements. Dans l'exemple précédent, ActionMode permet de s'assurer que l'instance ActionMode n'est pas recréée si elle est déjà active. Pour cela, vérifiez si le membre est nul avant de démarrer le mode d'action.

Créer un menu pop-up

Image montrant un menu pop-up dans l&#39;application Gmail, ancré au bouton à développer en haut à droite
Figure 4 : Menu pop-up de l'application Gmail, ancré sur le bouton à développer en haut à droite.

Un PopupMenu est un menu modal ancré à un View. Elle apparaît en dessous de la vue ancrée s'il y a de l'espace, ou au-dessus de la vue dans le cas contraire. Il est utile pour:

  • Un menu à développer pour les actions liées à un contenu spécifique, comme les en-têtes d'e-mails de Gmail, comme illustré dans la figure 4.
  • Ajout d'une deuxième partie d'une phrase de commande, par exemple un bouton marqué Add (Ajouter) qui génère un menu contextuel avec différentes options Add (Ajouter).
  • Fourniture d'un menu semblable à Spinner qui ne conserve pas de sélection persistante

Si vous définissez votre menu au format XML, procédez comme suit pour afficher le menu pop-up:

  1. Instanciez un PopupMenu avec son constructeur, qui utilise l'Context de l'application actuelle et le View auquel le menu est ancré.
  2. Utilisez MenuInflater pour gonfler votre ressource de menu dans l'objet Menu renvoyé par PopupMenu.getMenu().
  3. Appelez PopupMenu.show().

Voici par exemple un bouton qui permet d'afficher un menu contextuel:

<ImageButton
    android:id="@+id/dropdown_menu"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="@string/descr_overflow_button"
    android:src="@drawable/arrow_drop_down" />

L'activité peut alors afficher le menu pop-up comme ceci:

Kotlin

findViewById<ImageButton>(R.id.dropdown_menu).setOnClickListener {
    val popup = PopupMenu(this, it)
    val inflater: MenuInflater = popup.menuInflater
    inflater.inflate(R.menu.actions, popup.menu)
    popup.show()
}

Java

findViewById(R.id.dropdown_menu).setOnClickListener(v -> {
    PopupMenu popup = new PopupMenu(this, v);
    popup.getMenuInflater().inflate(R.menu.actions, popup.getMenu());
    popup.show();
});

Le menu est fermé lorsque l'utilisateur sélectionne un élément ou appuie en dehors de la zone de menu. Vous pouvez écouter l'événement "Ignorer" à l'aide de PopupMenu.OnDismissListener.

Gérer les événements de clic

Pour effectuer une action lorsque l'utilisateur sélectionne un élément de menu, implémentez l'interface PopupMenu.OnMenuItemClickListener et enregistrez-la avec votre PopupMenu en appelant setOnMenuItemclickListener(). Lorsque l'utilisateur sélectionne un élément, le système appelle le rappel onMenuItemClick() dans votre interface.

Ce processus est illustré dans l'exemple suivant :

Kotlin

fun showMenu(v: View) {
    PopupMenu(this, v).apply {
        // MainActivity implements OnMenuItemClickListener.
        setOnMenuItemClickListener(this@MainActivity)
        inflate(R.menu.actions)
        show()
    }
}

override fun onMenuItemClick(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.archive -> {
            archive(item)
            true
        }
        R.id.delete -> {
            delete(item)
            true
        }
        else -> false
    }
}

Java

public void showMenu(View v) {
    PopupMenu popup = new PopupMenu(this, v);

    // This activity implements OnMenuItemClickListener.
    popup.setOnMenuItemClickListener(this);
    popup.inflate(R.menu.actions);
    popup.show();
}

@Override
public boolean onMenuItemClick(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.archive:
            archive(item);
            return true;
        case R.id.delete:
            delete(item);
            return true;
        default:
            return false;
    }
}

Créer un groupe de menus

Un groupe de menu est un ensemble d'éléments de menu qui partagent certaines caractéristiques. Avec un groupe, vous pouvez effectuer les opérations suivantes:

Vous pouvez créer un groupe en imbriquant des éléments <item> dans un élément <group> de votre ressource de menu ou en spécifiant un ID de groupe avec la méthode add().

Voici un exemple de ressource de menu comprenant un groupe:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_save"
          android:icon="@drawable/menu_save"
          android:title="@string/menu_save" />
    <!-- menu group -->
    <group android:id="@+id/group_delete">
        <item android:id="@+id/menu_archive"
              android:title="@string/menu_archive" />
        <item android:id="@+id/menu_delete"
              android:title="@string/menu_delete" />
    </group>
</menu>

Les éléments du groupe apparaissent au même niveau que le premier élément : les trois éléments du menu sont frères. Toutefois, vous pouvez modifier les caractéristiques des deux éléments du groupe en référençant l'ID du groupe et en utilisant les méthodes précédentes. De plus, le système ne sépare jamais les éléments groupés. Par exemple, si vous déclarez android:showAsAction="ifRoom" pour chaque élément, ils apparaissent tous les deux dans la barre d'action ou les deux apparaissent dans le débordement d'action.

Utiliser des éléments de menu cochés

Figure 5. Sous-menu avec des éléments cochés.

Un menu peut servir d'interface pour activer et désactiver des options, en utilisant une case à cocher pour les options autonomes ou des cases d'option pour les groupes d'options mutuellement exclusives. La figure 5 montre un sous-menu comportant des éléments que vous pouvez cocher à l'aide de cases d'option.

Vous pouvez définir le comportement coché pour des éléments de menu individuels à l'aide de l'attribut android:checkable dans l'élément <item>, ou pour un groupe entier avec l'attribut android:checkableBehavior dans l'élément <group>. Par exemple, vous pouvez cocher tous les éléments de ce groupe de menus à l'aide d'une case d'option:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item android:id="@+id/red"
              android:title="@string/red" />
        <item android:id="@+id/blue"
              android:title="@string/blue" />
    </group>
</menu>

L'attribut android:checkableBehavior accepte l'une des valeurs suivantes:

single
Un seul élément du groupe peut être coché, ce qui génère des cases d'option.
all
Tous les éléments peuvent être cochés, ce qui génère une case à cocher.
none
Aucun élément n'est coché.

Vous pouvez appliquer un état coché par défaut à un élément à l'aide de l'attribut android:checked dans l'élément <item> et le modifier dans le code avec la méthode setChecked().

Lorsqu'un élément coché est sélectionné, le système appelle votre méthode de rappel respective, telle que onOptionsItemSelected(). C'est ici que vous définissez l'état de la case à cocher, car une case à cocher ou une case d'option ne change pas automatiquement son état. Vous pouvez interroger l'état actuel de l'élément (tel qu'il était avant que l'utilisateur ne le sélectionne) à l'aide de isChecked(), puis définir l'état coché avec setChecked(). Ce processus est illustré dans l'exemple suivant:

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.vibrate, R.id.dont_vibrate -> {
            item.isChecked = !item.isChecked
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.vibrate:
        case R.id.dont_vibrate:
            if (item.isChecked()) item.setChecked(false);
            else item.setChecked(true);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Si vous ne définissez pas l'état coché de cette manière, l'état visible de la case à cocher ou de la case d'option ne change pas lorsque l'utilisateur la sélectionne. Lorsque vous définissez l'état, l'activité conserve l'état coché de l'élément. Ainsi, lorsque l'utilisateur ouvre le menu ultérieurement, l'état coché que vous avez défini est visible.

Ajouter des éléments de menu en fonction d'un intent

Parfois, vous souhaitez qu'un élément de menu lance une activité à l'aide d'un Intent, qu'il s'agisse d'une activité dans votre application ou dans une autre application. Lorsque vous connaissez l'intent que vous souhaitez utiliser et que vous avez un élément de menu spécifique qui le lance, vous pouvez exécuter l'intent avec startActivity() lors de la méthode de rappel appropriée, telle que le rappel onOptionsItemSelected().

Toutefois, si vous n'êtes pas certain que l'appareil de l'utilisateur contient une application qui gère l'intent, l'ajout d'un élément de menu qui l'appelle peut entraîner un élément de menu non fonctionnel, car l'intent peut ne pas correspondre à une activité. Pour résoudre ce problème, Android vous permet d'ajouter dynamiquement des éléments de menu à votre menu lorsqu'Android trouve des activités sur l'appareil qui gèrent votre intent.

Pour ajouter des éléments de menu en fonction des activités disponibles qui acceptent un intent, procédez comme suit:

  1. Définissez un intent avec la catégorie CATEGORY_ALTERNATIVE ou CATEGORY_SELECTED_ALTERNATIVE, ou les deux, ainsi que toute autre exigence.
  2. Appelez Menu.addIntentOptions(). Android recherche ensuite toutes les applications pouvant exécuter l'intent et les ajoute à votre menu.

Si aucune application installée ne répond à l'intent, aucun élément de menu n'est ajouté.

Ce processus est illustré dans l'exemple suivant :

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    super.onCreateOptionsMenu(menu)

    // Create an Intent that describes the requirements to fulfill, to be
    // included in the menu. The offering app must include a category value
    // of Intent.CATEGORY_ALTERNATIVE.
    val intent = Intent(null, dataUri).apply {
        addCategory(Intent.CATEGORY_ALTERNATIVE)
    }

    // Search and populate the menu with acceptable offering apps.
    menu.addIntentOptions(
            R.id.intent_group,  // Menu group to which new items are added.
            0,                  // Unique item ID (none).
            0,                  // Order for the items (none).
            this.componentName, // The current activity name.
            null,               // Specific items to place first (none).
            intent,             // Intent created above that describes the requirements.
            0,                  // Additional flags to control items (none).
            null)               // Array of MenuItems that correlate to specific items (none).

    return true
}

Java

@Override
public boolean onCreateOptionsMenu(Menu menu){
    super.onCreateOptionsMenu(menu);

    // Create an Intent that describes the requirements to fulfill, to be
    // included in the menu. The offering app must include a category value
    // of Intent.CATEGORY_ALTERNATIVE.
    Intent intent = new Intent(null, dataUri);
    intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

    // Search and populate the menu with acceptable offering apps.
    menu.addIntentOptions(
         R.id.intent_group,         // Menu group to which new items are added.
         0,                         // Unique item ID (none).
         0,                         // Order for the items (none).
         this.getComponentName(),   // The current activity name.
         null,                      // Specific items to place first (none).
         intent,                    // Intent created above that describes the requirements.
         0,                         // Additional flags to control items (none).
         null);                     // Array of MenuItems that correlate to specific items (none).

    return true;
}

Pour chaque activité fournissant un filtre d'intent correspondant à l'intent défini, un élément de menu est ajouté, en utilisant la valeur du android:label du filtre d'intent comme titre de l'élément de menu et l'icône de l'application comme icône de l'élément de menu. La méthode addIntentOptions() renvoie le nombre d'éléments de menu ajoutés.

Ajouter votre activité à d'autres menus

Vous pouvez proposer les services de votre activité à d'autres applications afin qu'elle puisse être incluse dans le menu des autres applications, en inversant les rôles décrits précédemment.

Pour être inclus dans d'autres menus d'application, définissez un filtre d'intent comme d'habitude, mais incluez les valeurs CATEGORY_ALTERNATIVE ou CATEGORY_SELECTED_ALTERNATIVE, ou les deux, pour la catégorie de filtre d'intent. Ce processus est illustré dans l'exemple suivant :

<intent-filter label="@string/resize_image">
    ...
    <category android:name="android.intent.category.ALTERNATIVE" />
    <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
    ...
</intent-filter>

Pour en savoir plus sur l'écriture de filtres d'intent, consultez la page Intents et filtres d'intent.