• Aucun résultat trouvé

Menu d'options Créer un menu

Chaque activité est capable d'avoir son menu propre. On peut définir un menu de manière programmatique en Java, mais la meilleure façon de procéder est en XML. Tout d'abord, la racine de ce menu est de type <menu> (vous arriverez à retenir ? ), et on ne peut pas vraiment le personnaliser avec des attributs, ce qui donne la majorité du temps :

Code : XML

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Code -->

</menu>

Ce menu doit être peuplé avec des éléments, et c'est sur ces éléments que cliquera l'utilisateur pour activer ou désactiver une fonctionnalité. Ces éléments s'appellent en XML des <item> et peuvent être personnalisés à l'aide de plusieurs attributs :

android:id, que vous connaissez déjà. Il permet d'identifier de manière unique un <item>. Autant d'habitude cet attribut est facultatif, autant cette fois il est vraiment indispensable, vous verrez pourquoi dans cinq minutes.

android:icon, pour agrémenter votre <item> d'une icône. android:title, qui sera son texte dans le menu.

Enfin, on peut désactiver par défaut un <item> avec l'attribut android:enabled="false".

Vous pouvez récupérer gratuitement et légalement les icônes fournies avec Android. Par rapport à l'endroit où se situe le SDK, vous les trouverez dans .\platforms\android-x\data\res\ avec x le niveau de l'API que vous utilisez. Il est plutôt recommandé d'importer ces images en tant que drawables dans notre application, plutôt que de faire référence à l'icône utilisée actuellement par Android, car elle pourrait ne pas exister ou être différente en fonction de la version d'Android qu'exploite l'utilisateur. Si vous souhaitez faire vos propres icônes, sachez que la taille maximale recommandée est de 72 pixels pour les hautes résolutions, 48 pixels pour les moyennes résolutions et 38 pixels pour les basses résolutions.

Le problème est que l'espace consacré à un menu est assez réduit, comme toujours sur un périphérique portable, remarquez. Afin de gagner un peu de place, il est possible d'avoir un <item> qui ouvre un sous-menu, et ce sous-menu sera à traiter comme tout autre menu. On lui mettra donc des items aussi. En d'autres termes, la syntaxe est celle-ci :

<item> <menu> <item /> <!-- d'autres items--> <item /> </menu> </item>

Le sous-menu s'ouvrira dans une nouvelle fenêtre, et le titre de cette fenêtre se trouve dans l'attribut android:title. Si vous souhaitez mettre un titre plutôt long dans cette fenêtre et conserver un nom court dans le menu, utilisez l'attribut

android:titleCondensed, qui permet d'indiquer un titre à utiliser si le titre dans android:title est trop long. Ces <item> qui se trouvent dans un sous-menu peuvent être modulés avec d'autres attributs, comme android:checkable auquel vous pouvez mettre true si vous souhaitez que l'élément puisse être coché, comme une CheckBox. De plus, si vous souhaitez qu'il soit coché par défaut, vous pouvez mettre android:checked à true. Je réalise que ce n'est pas très clair, aussi vous proposé-je de regarder les deux figures suivantes : la première utilise android:titleCondensed="Item 1", la deuxième android:title="Item 1 mais avec un titre plus long quand même".

Le titre est condensé

Le titre est plus long

Enfin, il peut arriver que plusieurs éléments se ressemblent beaucoup ou fonctionnent ensemble, c'est pourquoi il est possible de les regrouper avec <group>. Si on veut que tous les éléments du groupe soient des CheckBox, on peut mettre au groupe l'attribut android:checkableBehavior="all", ou, si on veut qu'ils soient tous des RadioButton, on peut mettre l'attribut android:checkableBehavior="single".

Voici un exemple de menu qu'il vous est possible de créer avec cette méthode : Code : XML

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/item1" android:title="Item 1"></item> <item android:id="@+id/item2" android:titleCondensed="Item 2" android:title="Item 2 mais avec un nom assez long quand même"> <menu>

<item android:id="@+id/item3" android:title="Item 2.1" android:checkable="true"/>

</menu> </item>

<item android:id="@+id/item5" android:title="Item 3" android:checkable="true"/>

<item android:id="@+id/item6" android:title="Item 4">

<group android:id="@+id/group1" android:checkableBehavior="all"> <item android:id="@+id/item7" android:title="Item 4.1"></item> <item android:id="@+id/item8" android:title="Item 4.2"></item> </group>

</item>

<group android:id="@+id/group2" android:enabled="false">

<item android:id="@+id/item9" android:title="Item 5.1"></item> <item android:id="@+id/item10" android:title="Item 5.2"></item> </group>

</menu>

Comme pour un layout, il va falloir dire à Android qu'il doit parcourir le fichier XML pour construire le menu. Pour cela, c'est très simple, on va surcharger la méthode boolean onCreateOptionsMenu (Menu menu) d'une activité. Cette méthode est lancée au moment de la première pression du bouton qui fait émerger le menu. Cependant, comme avec les boîtes de dialogue, si vous souhaitez que le menu évolue à chaque pression du bouton, alors il vous faudra surcharger la méthode boolean

onPrepareOptionsMenu (Menu menu).

Pour parcourir le XML, on va l'inflater, eh oui ! encore une fois ! Encore un petit rappel de ce qu'est inflater ? To inflate, c'est désérialiser en français, et dans notre cas c'est transformer un objet qui n'est décrit qu'en XML en véritable objet qu'on peut manipuler. Voici le code type dès qu'on a constitué un menu en XML :

Code : Java

@Override

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

MenuInflater inflater = getMenuInflater(); //R.menu.menu est l'id de notre menu

inflater.inflate(R.menu.menu, menu); return true;

}

Si vous testez ce code, vous remarquerez tout d'abord que, contrairement au premier exemple, il n'y a pas assez de place pour contenir tous les items, c'est pourquoi le 6e item se transforme en un bouton pour afficher les éléments cachés, comme à la figure suivante.

Un bouton permet d'accéder aux

autres items

Ensuite vous remarquerez que les items 4.1 et 4.2 sont décrits comme Checkable, mais ne possèdent pas de case à cocher. C'est parce que les seuls <item> que l'on puisse cocher sont ceux qui se trouvent dans un sous-menu.

fonction MenuItem setEnabled (boolean activer) (le MenuItem retourné est celui sur lequel l'opération a été effectuée, de façon à pouvoir cumuler les setters).

Un setter est une méthode qui permet de modifier un des attributs d'un objet. Un getter est une méthode qui permet, elle, de récupérer un attribut d'un objet.

Vous pouvez aussi si vous le désirez construire un menu de manière programmatique avec la méthode suivante qui s'utilise sur un Menu :

Code : Java

MenuItem add (int groupId, int objectId, int ordre, CharSequence titre)

Où :

groupId permet d'indiquer si l'objet appartient à un groupe. Si ce n'est pas le cas, vous pouvez mettre Menu.NONE. objectId est l'identifiant unique de l'objet, vous pouvez aussi mettre Menu.NONE, mais je ne le recommande pas. ordre permet de définir l'ordre dans lequel vous souhaitez le voir apparaître dans le menu. Par défaut, l'ordre respecté est celui du fichier XML ou de l'ajout avec la méthode add, mais avec cette méthode vous pouvez bousculer l'ordre établi pour indiquer celui que vous préférez. Encore une fois, vous pouvez mettre Menu.NONE.

titre est le titre de l'item.

De manière identique et avec les mêmes paramètres, vous pouvez construire un sous-menu avec la méthode suivante : Code : Java

MenuItem addSubMenu (int groupId, int objectId, int ordre, CharSequence titre)

Et c'est indispensable de passer le menu à la superclasse comme on le fait ?

La réponse courte est non, la réponse longue est non, mais faites-le quand même. En passant le menu à l'implémentation par défaut, Android va peupler le menu avec des items systèmes standards. Alors, en tant que débutants, vous ne verrez pas la différence, mais si vous devenez des utilisateurs avancés, un oubli pourrait bien vous encombrer.