Développement d’applications unifiées sous Androïd 4.0

#android#ide#mobile

Les développeurs d’applications Androïd se sont pendant longtemps heurtés à la variété de produits utilisant la plateforme mobile. En effet, ne pas savoir sur quel support une application est utilisée est problématique pour fournir un confort d’utilisation optimal.

Androïd 4.0 apporte un élément de réponse à ce problème en proposant la première version du système unifiant le support des smartphones et des appareils de type tablette ; cette nouvelle version permet donc de créer des applications uniques, réduisant la rupture instaurée depuis le lancement d’Androïd 3.0 destiné à un usage sur tablettes uniquement. Cette différentiation qui contraignait les développeurs à maintenir multiples versions du code de leurs applications étant révolue, cet article propose un premier état des lieux du développement d’une application fonctionnant sur mobiles et tablettes.

Sélectionner les appareils autorisés à utiliser l’application et fournir les ressources adéquates

La première étape pour développer une application supportant différents formats d’appareil est de déclarer les tailles d’écran que l’application supportera dans le fichier AndroidManifest.xml. Pour cela, il suffit de renseigner la balise .

Par exemple, pour une application supportant à la fois mobiles et tablettes :

Il faut ensuite fournir plusieurs formats pour les ressources affichées sur des écrans de différentes densités (pour une zone de même taille, deux écrans de densité différente ne proposent pas la même quantité de pixels).

Par exemple, une image destinée à être utilisée sur un écran de faible densité occupe moins de place pour s’adapter à un écran plus dense. Il est donc recommandé de définir cette ressource pour chaque densité d’écran afin de conserver une taille d’affichage constante.

Fournir ces ressources consiste simplement à créer la structure de dossiers adéquate, le système s’adaptant ensuite automatiquement à l’écran utilisé.

Par défaut, Androïd redimensionne l’interface de l’application pour qu’elle s’ajuste à l’écran utilisé. Cependant, il est dans certains cas nécessaire d’adapter plus en finesse la taille et la position de certains éléments plutôt que de laisser le système agir de lui-même. Pour ce faire, il faut fournir à l’application des fichiers d’interface (« layouts ») spécifiques aux tailles d’écran déclarées dans le fichier AndroidManifest.xml. Ainsi, pour chaque format, on ajoute un dossier portant un nom spécifique et comportant les ressources associées. Le système choisit alors automatiquement le layout approprié.

Avant l’arrivée d’Androïd 3.2, quatre catégories permettaient de distinguer les écrans en fonction d’un seuil minimal sur leur résolution exprimée en « dp » (unité permettant de caractériser la résolution de l’écran de manière indépendante de sa densité) :

Cette hiérarchie est devenue insuffisante pour spécifier autant de layouts que de formats d’écrans existant. La méthode recommandée depuis Androïd 3.2 est de répartir ces fichiers selon la largeur minimale nécessaire en « dp ». Par exemple, pour une application proposant des layouts différents pour mobiles, tablettes 7 pouces et tablettes 10 pouces, il faut définir trois dossiers :

-> res/layout/ # Pour mobiles (par défaut)
-> res/layout-sw600dp/ # Pour les tablettes 7 pouces
-> res/layout-sw720dp/ # Pour les tablettes 10 pouces

Cette première approche améliore considérablement le rendu d’une application sur plusieurs supports mais ne permet pas d’optimiser totalement le potentiel de chaque type d’appareil : une tablette de par son écran de grande taille permet l’affichage de plus de contenu simultanément alors que ce même contenu doit être réparti sur plusieurs vues pour un mobile par exemple.

Optimiser l’interface selon l’appareil en utilisant les fragments

Instaurés depuis la version 3.0, les fragments permettent de décomposer les fonctionnalités d’une application en plusieurs blocs affichables et limitent ainsi les changements d’activité, notamment pour une application composée de plusieurs volets. Les fragments sont particulièrement utiles pour un usage sur des appareils disposant d’un grand écran car ils permettent de combiner ou d’inter-changer facilement des parties de l’interface.

Afin d’être mis en place efficacement, les fragments doivent être programmés de manière modulaire et réutilisable. Chaque fragment décrit son propre cycle de vie, gère lui même les interventions de l’utilisateur et dispose de ses propres accesseurs.

Sous Androïd 4.0, ces éléments représentent également la solution pour le développement d’une application s’adaptant au profil d’appareil utilisé : la conception de l’interface doit alors être pensée comme un ensemble de fragments agencés différemment en fonction de la taille d’écran disponible. Ce comportement s’illustre facilement avec l’exemple d’un lecteur de flux RSS : un appareil disposant d’un petit écran affiche dans un premier temps une vue composée d’une liste d’articles. Lors de la sélection d’un article, l’affichage bascule sur une vue laissant place au contenu de cet article. Avec un grand écran, ces deux fragments sont affichés côte à côte, la sélection d’un élément de la liste ayant pour effet la mise a jour de la vue de détail de l’article.

D’un point de vue technique, il y a deux façons de produire ce comportement :

Utiliser une activité unique regroupant les deux fragments, et gérer dynamiquement l’affichage de ceux-ci selon la taille de l’écran depuis le code de l’activité. Cette approche bien que fonctionnelle peut rapidement devenir complexe à maintenir pour une application proposant multiples agencements de fragments (afin d’obtenir la taille de l’écran il suffit d’appeler : getResources().getConfiguration() qui renvoie un objet de type Configuration proposant un champ screenlayout).

Utiliser plusieurs activités et plusieurs fragments : on utilise une activité principale dont le layout inclut les deux fragments pour un grand écran et un seul fragment pour les petites tailles. Le système choisit alors automatiquement le layout approprié. Lorsque l’activité principale est sollicitée elle doit, si le second fragment n’est pas présent, instancier une seconde activité hébergeant celui-ci sinon le mettre à jour.

Dans le cas de l’application proposant un lecteur de flux RSS, voici ce que doit réaliser la seconde méthode :

Il faut donc définir deux « layouts » pour l’activité principale (activité 1) : le premier dédié aux petits écrans ne comportant que le fragment affichant la vue de liste des articles. Celui-ci est déclaré dans le dossier res/layout/

Le second destiné aux grands écrans, affichant à gauche la liste d’articles et à droite la vue de détail, placée dans le répertoire res/layout-sw600dp/

Lorsque l’utilisateur sélectionne un élément de la liste d’articles, le comportement de l’activité principale (activité 1) est le suivant :

Si le fragment de détail est disponible dans le « layout » courant, l’activité 1 ordonne au fragment de détail de se mettre à jour

Si le fragment de détail n’est pas présent, l’activité 1 instancie l’activité 2 qui prend alors le relais et affiche la vue de détail.

L’activité 2 n’étant appelée que dans le cas de petits écrans, son layout ne sera déclaré qu’une seule fois dans le répertoire correspondant. Les interfaces par défaut étant définies, l’étape suivante consiste à déclarer la fonction de l’activité principale (activité 1) qui écoute le signal émis lorsqu’un élément de la liste est sélectionné :

L’utilisation de fragments est essentielle pour produire une application multi-supports car elle permet de proposer une interface ajustée aux différents appareils du marché.

Utilisation de la barre d’actions

Egalement introduite depuis Androïd 3.0, la barre d’actions (« ActionBar ») offre la possibilité d’obtenir aisément une barre de menus s’intégrant à l’interface du système et permettant d’effectuer diverses actions grâce à des boutons ou de changer le mode d’affichage via un menu d’onglets. Son fonctionnement n’évolue pas dans cette nouvelle mouture de l’environnement. Cependant, quelques ajustements sont de rigueur pour qu’une application supportant plusieurs formats d’écran en tire le meilleur parti. En ce qui concerne les boutons d’action : une fois définis, ceux-ci sont stockés par défaut dans le menu options à droite de la barre d’actions ou accessibles depuis une touche de l’appareil. Il est également possible de forcer ces boutons à apparaitre directement dans la barre d’actions en utilisant lors de leur déclaration l’attribut : android:showAsAction= »always « .

Dans le cas d’une application combinant le support des mobiles et des tablettes, il faut éviter au maximum de forcer l’apparition de ces menus dans la barre supérieure car la place est limitée. Pour cela, une option est préférable : android:showAsAction= »ifRoom ». Le système ajuste alors, selon la place disponible, les éléments à afficher.

Il est également recommandé de fournir une icône pour chaque action en plus de son texte descriptif et de compléter sa déclaration : android:showAsAction= »ifRoom|withText ». Ainsi, selon la largeur disponible, le descriptif de l’action est automatiquement masqué.

Sur un mobile, les onglets se placent sous la barre d’actions et il est possible de faire glisser la liste latéralement lorsque leur nombre devient trop important. Sur tablette, les onglets se logent dans la barre d’actions. Ceux-ci sont automatiquement rassemblés si la taille ne permet pas de les afficher sur une seule ligne. Androïd 4.0 ajoute également une nouveauté permettant de solutionner le problème de la faible quantité de boutons d’action affichables dans la barre supérieure. Il s’agit de l’option uiOptions= »splitActionBarWhenNarrow » qui se déclare dans le manifeste de l’application ou de l’activité. Sur de grands écrans, cette option n’a pas d’effets alors que sur des écrans de smartphones, les boutons d’action se retrouvent projetés en bas de l’écran.

Il est également bon d’appeler la méthode « setDisplayShowHomeEnabled(false) » afin d’enlever la barre de titre et gagner quelques précieux pixels d’affichage lorsque cela est possible.

Androïd 4.0 est le premier essai de la plateforme visant à rassembler le monde des tablettes et celui des smartphones. Cette mouture reprend en grande partie les éléments instaurés depuis la version 3.0 dédiée aux tablettes. Ceci permet aux développeurs souhaitant proposer des applications uniformisées un travail standardisé et d’harmoniser les interfaces au travers de la multitude de produits supportés par Androïd. Cependant, la répartition des versions du système d’exploitation est encore très fragmentée et cette nouvelle édition ne sera pas supportée par tous les appareils. Les développeurs devront penser pendant quelques temps encore à rendre leurs applications compatibles avec les appareils plus anciens. Pour cela, Google fournit un package de compatibilité afin d’utiliser les nouveautés telles que les fragments sur les anciennes versions de la plateforme.

Il est possible de retrouver l’intégralité de cet article dans le numéro 147 de Décembre 2011 du magazine « Programmez ».