Android : Un Slide Menu en deux clics

Publié dans: 

Les Slide Menus sont de plus en plus utilisés et on les retrouve notamment au niveau des applications Facebook, Gmail etc.
Ce menu permet de mieux gérer l'espace puisqu'il apparait et disparait à la demande. Il permet également de disposer de l'ensemble des fonctionnalités de notre application. L'autre spécificité de ce menu est qu'il apparait par un simple mouvement du doigt de gauche vers la droite.

Dans le présent article je détaillerai étape par étape la construction d'une application qui donne l’heure et la date actuelles partout dans le monde. Elle aura un menu exposant les Time Zones. Le clic sur un élément nous donnera l'heure actuelle dans ce fuseau horaire.

Nous commencerons par exposer la structure du fichier XML de notre activité. Nous passerons ensuite à la définition des éléments de notre Slide Menu. Enfin, nous décrirons la création et la manipulation du Slide Menu par l'activité (Java) à partir des objets : DrawerLayout, ListView et ActionBarDrawerToggle.

(Pour mieux suivre le code source de l’exemple est disponible ici)

STRUCTURE DU FICHIER XML DE L’ACTIVITÉ

 

Le fichier XML doit respecter la structure suivante : un DrawerLayout dans lequel nous mettons un Layout qui contiendra le contenu de notre écran et une ListView qui contiendra les éléments de notre menu.

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/menu_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
 
<!-- The LinearLayout consumes the entire space available 
using match_parent in both dimensions. -->
 
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
 
<TextView
android:id="@+id/time_zone_current_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
 
<!-- The menu elements ListView. -->
 
<ListView
android:id="@+id/menu_elements"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#123"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"/>
 
</android.support.v4.widget.DrawerLayout>

 

DÉFINITION DE LA STRUCTURE DES ÉLÉMENTS DU MENU

 

Il faut également définir la structure des éléments du SlideMenu dans le fichier "element_menu.xml". Pour notre exemple nous avons un élément qui contient uniquement un TextView. Mais rien n'empêche d'avoir des éléments à structures complexes ou un menu ayant des éléments de différentes compositions.

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/menu_time_zone_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:text="@string/hello_world"
android:textColor="#fff"/>

 

IMPLÉMENTATION DE L’ACTIVITÉ

 

Au niveau du code Java nous disposons principalement des trois objets suivants :

private DrawerLayout menuLayout; //Layout Principal
private ListView menuElementsList; //Menu
private ActionBarDrawerToggle menuToggle; //Gère l'ouverture et la fermeture du menu

 

Le SlideMenu peut être appelé par le bouton home de notre activité, pour ce faire nous devons activer ce dernier.

getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);

 

Nous commençons par récupérer le layout et la liste.

menuLayout = (DrawerLayout) findViewById(R.id.menu_layout);
menuElementsList = (ListView) findViewById(R.id.menu_elements);

 

Nous ajoutons un effet à appliquer quand le menu est ouvert, et nous spécifions la direction d'ouverture du SlideMenu (ici GravityCompat.START donc de gauche à droite).

menuLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

Attention, ceci doit être la même valeur que celle spécifiée en XML dans la ListView (android:layout_gravity="start")


Nous créons un adapter et ajoutons la liste des éléments du SlideMenu. Ensuite nous appliquons l’adapter à notre menuElementsList.

menuElementsList.setAdapter(adapter);

 

Passons maintenant à la création du menuToggle qui gérera l’ouverture et la fermeture du menu.

menuToggle = new ActionBarDrawerToggle(this,menuLayout, R.drawable.ic_drawer,R.string.drawer_open,R.string.drawer_close) {
//Exécutée à la fermeture du menu
public void onDrawerClosed(View view) {
      getActionBar().setTitle(activityTitle);
      invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
//Exécutée à l’ouverture du menu
public void onDrawerOpened(View drawerView) {
      getActionBar().setTitle(menuTitle);
      invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
menuLayout.setDrawerListener(menuToggle);

 

Afin d’interagir avec les clics sur les éléments du SlideMenu, nous devons créer un OnItemClickListener.

menuElementsList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View view, int position,long id) {
... Faites ce que vous désirez suite au clic sur l’élément ayant comme index "position"...
}
});

 

Et pour finir, comment masquer les éléments du menu optionnel une fois que notre SlideMenu est ouvert et comment les réafficher à sa fermeture ?
Rappelons que la méthode onPrepareOptionsMenu() est appelée à l’ouverture et à la fermeture de notre SlideMenu via invalidateOptionsMenu().
Ceci n'est nullement obligatoire. Vous pouvez garder les actions de votre menu optionnel affichées. Pour cela ne faites pas appel à la méthode invalidateOptionsMenu().

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
      // Cache l'élément du menu optionnel à l'ouverture et le fait réapparaitre à la fermeture
      boolean drawerOpen = menuLayout.isDrawerOpen(menuElementsList);
      menu.findItem(R.id.action_search).setVisible(!drawerOpen);
      return super.onPrepareOptionsMenu(menu);
}

 

J’ai essayé de commenter au mieux le code source.
Si vous avez des questions n’hésitez pas à poster vos commentaires.