mercredi 20 juin 2012

Retour d’expérience d’un ergonome sur Android

Le projet voltaire est une application d’apprentissage d’orthographe disponible sur l’AppStore : http://itunes.apple.com/fr/app/orthographe-projet-voltaire et sur google play : https://play.google.com/store/apps/details?id=com.projet.voltaire.


A l’occasion de la réalisation de la couche de présentation de cette application sous Android, je vous propose de faire un retour d’expérience sur les possibilités de cet environnement, avec un œil orienté ergonomie bien sûr. Attention, car malgré ma longue expérience en développement d’IHM, je reste un newbie sur ce système. Ce qui suit n’est donc que le fruit d’une trentaine de jours de développement, intensifs malgré tout.

  L’environnement de développement


Pour l’habitué aux environnements Java, le démarrage sous Android se fait en toute simplicité : une installation de la dernière version d’Eclipse suivi de l’installation du SDK Android et enfin du plugin ADT pour Eclipse fournit un environnement de développement opérationnel.
La première réelle difficulté a été de choisir, parmi les 14 versions disponibles, quelle serait celle utilisée pour notre développement. On est parti sur une version 2.1, déjà très riche fonctionnellement, et apte à tourner sur plus de 80% des devices en France.
L’excellente qualité de la documentation en ligne et la profusion de tutoriaux sur la toile, m’ont permis de progresser rapidement. L’autoformation est tout à fait envisageable et j’évalue le temps de montée en compétence pour un bon programmeur JAVA client riche (GWT, ou Swing) entre 5 et 10j. L’analogie avec l’API Swing est assez saisissante (mécanique événementielle, couplage lâche assuré par des interfaces d’écoute, dessin des composants via une API de dessin 2D). Cependant, on a ici, quelque chose d’emblée beaucoup plus mature et qui ne souffre pas d’un historique à rallonge avec de multiples couches logicielles (Ex : AWT).

Les sources de l’API android ne sont proposées au téléchargement via le SDK Manager qu’à partir la version 4.0. C’est un petit peu plus complexe à télécharger pour les autres versions, mais je vous conseille vivement de configurer Eclipse sur ces sources pour pouvoir entrer en debug dans l’API. De même, un petit coup d’œil dans le répertoire d’installation du SDK android, vous permettra par exemple de voir comment sont organisées les ressources graphiques d’Android.

  L’émulateur

Le SDK embarque un émulateur permettant de faire tourner son application et de la débuguer en temps réel. Mon retour d’expérience est plutôt mitigé.
Il reproduit fidèlement le rendu du device mais trouve ses limites précisément sur l’expérience utilisateur : interactions tactiles difficilement simulables, le rendu pas en taille réelle ne permet d’évaluer les problématiques de lisibilité, rendu sur tablette non émulable en 2.1.
En outre, l’émulateur est bien trop lent à démarrer : environ 5 minutes entre 2 runs si l’émulateur n’est pas démarré, 2 à 3 minutes sinon. Cela dépend de la machine bien sûr, mais c’est beaucoup trop long quand, en phase d’industrialisation, on doit lancer de multiple fois pour intégrer les ressources graphiques faites par le designer.
Nous avons fait le choix de se procurer 3 devices : une Galaxy Tab 10" (catégorisé xlarge par Android), un galaxy Mini (catégorisé small par Android), une tablette Archos 7p (catégorisée large par Android). L’installation du device a été le plus souvent très facile : reconnu immédiatement ou pilote téléchargé automatiquement après branchement sur le port USB. L’Archos a nécessité une recherche et une installation manuelle du pilote USB ADB sur internet. Au final, le développement, device toujours branché, est devenu la règle, procurant une productivité de développement très très intéressante.
Je ne le répéterai jamais assez : l’expérience utilisateur est bien plus critique en situation de mobilité que sur desktop. Le projet Voltaire propose par exemple d’identifier une faute d’orthographe en pointant le, ou les mots en erreur. On s’est rendu compte, lorsque le mot était court (Ex : erreur d’accent sur le a) et que le device était petit, que le pointage devenait très difficile. Ce problème n’était pas détectable sur l’émulateur où le pointeur est simulé par un clic souris. On l’a résolu en mettant une tolérance sur les zones « touchables » et en testant sur le device le plus petit.   
Au final, je conseille de limiter l’usage de l’émulateur à la phase de test, où il permettra de tester le rendu sur des résolutions exotiques, ou sur des devices que l’on ne peut se procurer.

  Une grande richesse fonctionnelle pour l’IHM

La philosophie de la programmation Android, repose sur la dissociation entre les vues et les contrôleurs. Ce principe est depuis longtemps admis en conception objet (design pattern MVC) mais est interprété sous Android de la façon suivante : les vues (arborescences de composants et politiques de placement par rapport à leur conteneur) sont décrites de manière déclarative dans des fichiers xml, tandis que les contrôleurs sont décrits programmatiquement dans des classes JAVA. Cependant, afin de pallier aux limites du déclaratif (cas d’une IHM à l’arborescence dynamique), il reste possible de déclarer ou modifier  les vues programmatiquement directement au sein des contrôleurs. C’est très puissant et plutôt bien vu, mais attention à ce que l’exception ne devienne pas la règle : en limitant au maximum les manipulations programmatiques de la structure des vues, on favorise la maintenabilité et on maximise l’intérêt du GUI designer.

Les drawables

L’une des grandes forces d’Android est qu’il permet un controle très fin du design. Tout le dessin des widgets Android est réalisé via des ressources externalisées : ces drawables étant facilement surchargeables, il est très facile d'en customiser le rendu

Android s’affranchit du phénomène de réduction de la taille des images sur des écrans à forte densité, en proposant de livrer les ressources graphiques en plusieurs tailles (0.75x, 1x, 1.5x, 2x) dans des sous répertoires dédiés. C’est élégant, car sans aucun impact sur le code, mais cela alourdit le poids global de l’application qui sera installée avec l’ensemble des ressources graphiques. A quand une optimisation pour n’installer que les ressources adaptées au device ?.  
D’autre part, un drawable n’est pas seulement définissable directement sur une ressource graphique,  il est possible de définir un drawable via un fichier xml.
Les barres de progression du projet voltaire sont ainsi définies de manière déclarative, ce qui permet de skinner leur couleur sans avoir à faire appel au graphiste :

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dip" />
            <gradient              
                android:angle="270"
                android:startColor="#FFFFFF"              
                android:endColor="@color/WoonozLightGray"
             />
        </shape>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dip" />
                <gradient              
                            android:angle="270"
                            android:startColor="@color/WoonozLightGreen"              
                            android:endColor="@color/WoonozDarkGreen" 
                />                          
            </shape>
        </clip>
    </item>
</layer-list>

Les styles

Le rendu visuel des composants graphiques est largement paramétrable et la notion de style permet de mutualiser ce rendu afin de garantir une cohérence au design. C’est à double tranchant, car le bon sens ergonomique, voudrait qu’on utilise les styles par défaut, au nom de la cohérence avec les autres applications. C’est sur ces bases qu’Apple ferme son système, en ne facilitant pas la tâche pour skinner une application iOS (Ex : il est très difficile de changer la couleur d’une barre de progression).
Rien de tel sous Android qui permet de tout faire, même si des esprits chagrins regretteront que cela ne se fasse pas sur la base de CSS mais sur des fichiers xml à la structure propriétaire.
A l’usage, le design de l’application est piloté par trois fichiers :
·         Colors.xml : contient la palette de couleurs de l’application
·         Themes.xml : décrit les styles à appliquer pour chacun des composants graphiques 
·         Styles.xml : décrit le contenu de chacun des styles
L’ensemble du design étant externalisable, il devient très simple de définir plusieurs skins, sans intervention sur le code. C’est d’ailleurs l’une des limitations d’Android, on ne peut changer le style d’un composant dynamiquement après son instanciation (contrairement à ce que l’on fait couramment en web).
Si la notion de style intéressera essentiellement le designer, elle nous à permis ponctuellement d’assurer quelques règles ergonomiques 

Sur l’exemple ci-dessous, on force la taille minimale des boutons à 47x47, ce qui correspond précisément à la surface minimale pour qu’une zone soit touchable par un doigt humain.

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

    <!-- Styles généraux -->
    <style name="WoonozButton" parent="@android:style/Widget.Button">
        <item name="android:textSize">12dp</item>
        <item name="android:gravity">center_vertical|center_horizontal</item>
        <item name="android:typeface">sans</item>
        <item name="android:textColor">@color/WoonozBlack</item>
        <item name="android:background">@drawable/woonoz_button</item>
        <item name="android:focusable">true</item>
        <item name="android:clickable">true</item>
        <item name="android:paddingLeft">15dp</item>
        <item name="android:paddingRight">15dp</item>
        <item name="android:paddingTop">10dp</item>
        <item name="android:paddingBottom">10dp</item>
         <item name="android:minWidth">47dp</item>
         <item name="android:minHeight">47dp</item>
    </style>
</resources>

Les 9 patch

),  Android permet d’exploiter les ressources graphiques sans déformation ni effet de pixellisation, quelle que soit la taille et la résolution de l’écran. Le travail du graphiste est considérablement réduit par la quasi absence de découpage des images (contrairement aux applications Web ou iOS par exmple). Enfin, en ne stockant en définitive que les pixels utiles, le poids global des ressources graphiques est considérablement réduit.
Le SDK fournit un outil permettant de transformer une image standard en un 9 patch. C’est un peu difficile à expliquer mais il s’agit de matérialiser par des pixels noirs dans le contour de l’image : les zones étirables d’une part, le sous rectangle réservé à l’affichage du contenu, d’autre part. A l’usage, j’ai trouvé l’outil un peu rudimentaire (le chemin du dernier fichier ouvert n’est pas sauvé, la pose des pixels sur des images de grande taille est fastidieuse), mais le concept est franchement plutôt génial.
Grace au 9 patch, une seule ressource (820 octets seulement), nous a permis d’afficher, sans effets disgracieux l’ensemble des boutons du projet Voltaire.

Cependant, les 9 patchs ne permettent pas de tout gérer : les photos et les images sans axe de symétrie ne sont pas toutes « 9 patchables ». Dans certains cas, les images ont du être retravaillées par le graphiste pour qu’on puisse placer des zones étirables.

Impossible d'étirer horizontalement


Ajout d'une bordure pour étirer horizontalement
Côté maintenance, on s’est demandé si la création des 9 patchs était à réaliser par le graphiste ou bien le développeur. Dans notre cas, c’est le développeur qui a maintenu les 9 patch. D’un côté, il pouvait visualiser le rendu directement dans l’application. D’un autre côté, à chaque relivraison d’une image par le graphiste, il a fallu redéfinir les patchs.  Egalement, comment s'assurer de la cohérence des patchs sur des ressources graphiques livrées en 4 ou 5 tailles ? Ceci ampute pas mal la capacité du développeur qui a autre chose à faire que de placer les patchs. Avec le recul, je pense que c’est un travail à réserver au graphiste, mais qu’il faut prévoir une formation spécifique.   

Gestion des différents types d’écrans

Contrairement à l’environnement iOS où la variabilité des tailles d’écrans et des résolutions est limitée par Apple (ce qui autorise une philosophie de placement des composants graphiques en absolu), la taille physique et la résolution de l’écran sont à considérer comme non déterminés, en raison du trop grand nombre de device.
En ergonomie logicielle, la taille physique et la résolution de l’écran, le rapport hauteur sur largeur, sont des éléments critiques pour organiser l’affichage. L’utilisateur doit avoir en permanence,  l’ensemble des informations utiles à la tâche en cours. Si, comme je le vois trop souvent sur des applications web, une partie des informations est cachée via des barres de défilement, l’expérience utilisateur est dégradée.
J’ai été très impressionné par ce que propose Android en la matière. Du classique d’abord, avec la possibilité de définir des politiques de placement (layouts) permettant de placer les sous vues en fonction de la position et de la taille de la vue parente. Cela permet de profiter de toute la surface d’affichage disponible et de privilégier les sous vues ergonomiquement plus importante en leur attribuant un poids plus important.

Plus originale est la possibilité d’avoir une vue spécifique en fonction du type d’écran (petit, normal, grand ou très grand), le tout sans écrire de code.  
Rendu pour smartphone

Rendu pour tablette

Quand on sait que cette mécanique s’applique aussi pour gérer le basculement entre les modes portrait et paysage, on comprend qu’Android fournit là un moyen de toujours adapter le contenu à la surface d’affichage réelle.
Le projet Voltaire tourne aussi bien sur des smartphone 2.7pouces (240x320) que sur des tablettes de plus de 10 pouces (1024x768). Sur les grands écrans, on profite de l’espace disponible pour afficher plus d’informations. Sur les petits écrans, il a fallu réduire les marges et les espacements entre composants pour ne pas perdre en lisibilité. Au final, on est arrivé à une optimisation ergonomique pour tout type d’écran, inimaginable pour une application web, le tout sans écrire de code (tout a été réalisé de manière déclarative). A bas les barres de défilement !

 Les animations

Android propose une API permettant de gérer les animations, à la fois très puissante et simple à mettre en œuvre.
  • C’est simple car le lancement se fait de manière asynchrone sans avoir à gérer de problématique multithread : il suffit de définir un modèle d’animation avec une durée, lorsqu’on l’applique sur une vue, android interpole les images automatiquement et joue l’animation de manière parfaitement fluide
  • C’est puissant car de nombreux types d’animations sont disponibles et qu’il est possible de surcharger le modèle pour des animations customisées (Ex : en modifiant le poids d’une vue dans son layout, on peut agrandir une partie d’un écran de manière animée en toute fluidité)
 Cette simplicité permet réellement de gérer de nombreux effets très intéressants, qu’il conviendra néanmoins d’utiliser avec parcimonie. Attention, en effet, à la pertinence ergonomique des animations, qui doivent chacune apporter une valeur ajoutée.
Pour le projet Voltaire, les animations nous ont permis de traiter les points suivants :
  • Design :
    • Les transitions entre écrans sont gérées avec un effet de défilement de pages de droite vers la gauche. Les animations de transition sont déclarées dans des fichers xml et mutualisées dans l’application grâce à la notion de style : pas une seule ligne de code
    • L’affichage du bandeau de réponse est géré avec un effet de translation combinée à un effet de fading permettant d’afficher le bandeau comme s’il surgissait de l’entête.
  • Ergonomie 
    • La problématique de lisibilité de la phrase sur petit écran a été résolue par un effet d’animation de type réduction : la phrase est affichée en gros caractères pendant la question (permettant un touché de la faute plus efficace) puis réduite pour permettre l’affichage de la règle



     Synthèse des problèmes rencontrés et des inconvénients


v      API
Ø      Impossible de passer un objet non Parceable entre deux écrans d’une même application
Ø      Problématique de mémoire suite à une reprise d’activité après libération de l’application (variables statiques non réinitialisées)
v      Technologie des 9 patch innovante, mais perfectible
Ø      Outil de création des 9 patch plutôt basique,
Ø      Problématique de cohérence des 9 patch en plusieurs résolutions,
Ø      Problématique de responsabilité sur la définition des 9 patch entre le développeur et le graphiste.
v      Trop grande souplesse de customisation ?
Ø      Conduit à un manque de cohérence des IHMs
v      Styles perfectibles
Ø      Les styles auraient gagné à s’appuyer sur les css comme JavaFX
Ø      Style non modifiable après instanciation du composant graphique
v      Design
Ø      Faible nombre de police
Ø      Impossible d’utiliser une police customisée de manière déclarative, uniquement de manière programmatique
v      Duplication des ressources
Ø      Fichiers de layout plus ou moins partiellement dupliqués lorsqu’on spécialise les layouts par type d’écran
Ø      Installation des ressources graphiques non optimisée : toutes les ressources sont systématiquement installées même si elles ne sont pas adaptées au device.
v      Déploiement
Ø      Démarrage pas entièrement gratuit
Ø      Déploiement multi version pas pratique

Conclusion

J’ai été assez bluffé par l’ergonomie de développement et par la qualité de la documentation. Certaines fonctions sont vraiment novatrices et l’ensemble est très bien intégré. Il faut bien reconnaitre, que j’ai pu, tout au long de mon expérience de programmation, me concentrer sur le fonctionnel de mon application, sans me disperser sur  des détails techniques.
J’ai également eu très peu de problématique de performance ou de mémoire, en tout cas pas plus que sur un développement pour desktop.

La richesse des fonctionnalités orientées vers le design et/ou l’ergonomie sont à mon avis, inégalées à ce jour. Ceci en fait un environnement très adapté à la réalisation d’applications à fort enjeu ergonomique. C'est pour moi le cas de toute application mobile à forte fréquence d’usage.
Par rapport à des applications webs, on retrouve la même liberté de design avec une productivité à mon avis très largement supérieure. La gestion du multi écran, très loin devant, et la simplicité de mise en œuvre des animations donnent une nouvelle longueur d’avance sur les applications webs.
Alors, Android, l’environnement de développement idéal pour réaliser des applications ergonomiques ?
Dans l’absolu, bien sur que non car la perfection n’est pas de ce monde. Paradoxalement, sa grande souplesse provoque un effet pervers très gênant : le manque de cohérence. En permettant de tout customiser, Android laisse la porte à la création de nouveaux composants graphiques, inconnus de l’utilisateur ainsi qu’à des écrans dont le look et la philosophie d’utilisation n’a rien à voir avec les applications standards Android. Les applications installées sur un device Android, ne se ressemblent pas et tendent à avoir une philosophie d’utilisation propre. Ceci se fait au dépend de l’utilisateur, qui ne peut s’appuyer sur des principes d’utilisation déjà connus, lors de la découverte d’une nouvelle application. 
Si un guide d’ergonomie est bien sur les rails, n’arrive-t-il pas trop tard et sera-t-il suffisant ? La certification serrée par Apple des applications publiées sur l’appStore, n’est à mon avis pas étrangère à la qualité de l’expérience utilisateur sur iOS et Google ferait bien de s’en inspirer.



Aucun commentaire:

Publier un commentaire