Translate

mardi 4 février 2014

Slide Menu

 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.
Le code source est disponible Code Source

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.

1. 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>

2. 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"/>

C'est déjà fini du côté XML. Passons maintenant du côté de l'activité pour voir comment interagir avec le menu.

3. 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 = newActionBarDrawerToggle(this,menuLayout, R.drawable.ic_drawer,R.string.drawer_open,R.string.drawer_close) {
//Exécutée à la fermeture du menu
publicvoidonDrawerClosed(View view) {
      getActionBar().setTitle(activityTitle);
      invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
//Exécutée à l’ouverture du menu
publicvoidonDrawerOpened(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(newOnItemClickListener() {
@Override
publicvoidonItemClick(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
publicbooleanonPrepareOptionsMenu(Menu menu) {
      // Cache l'élément du menu optionnel à l'ouverture et le fait réapparaitre à la fermeture
      booleandrawerOpen = menuLayout.isDrawerOpen(menuElementsList);
      menu.findItem(R.id.action_search).setVisible(!drawerOpen);
      returnsuper.onPrepareOptionsMenu(menu);
}
  
Le code source est disponible Code Source