Android :: les UI complexes

Après d'importants efforts, Android propose depuis Ice Cream Sandwich un ensemble de Guidelines pour réaliser des interfaces utilisateurs. Google espère ainsi homogénéiser le look & feel des applications et semble en bonne voie d'y parvenir depuis la sortie de Ice Cream Sandwich (version 4.0 d'Android). Mais même en suivant au mieux les recommandations de Google, il arrive parfois que l'on doive sortir des "normes", c'est ce que nous appellerons des "UI complexes".

Pourquoi des UI complexes sur mobile ?

On peut rencontrer cette problématique pour différentes raisons :

  • une UI novatrice qui propose un type d'intéraction nouvelle aux utilisateur/TRICEs (ex: la première boîte à Meuuh)
  • un processus nouveau ou peu fréquent sur mobile (ex : déplacer un fichier)
  • une contrainte technique / humaine qui rend l'interface complexe et peu intuitive (ex: un service d'authentification nécessitant deux mots de passe, ou encore la mauvaise idée d'interface iPhone à laquelle mon client tient mordicus...)

En informatique, nous essayons le plus souvent de réaliser des interfaces hommes-machines (ou User Interface / UI) intuitives. Et cela est encore plus vrai dans le contexte de la mobilité. En effet, les utilisateur/TRICEs ont peu de temps, et veulent interagir rapidement avec leur mobile. Les solutions habituelles à ce problème comme l'affichage d'une aide ou des info-bulles (tooltip) sont hors de portée : l'espace physique pour afficher une aide en bonne et due forme manque dans un contexte mobile tandis que les info-bulles ne sont disponibles que depuis Ice Cream Sandwich et encore, uniquement pour les boutons de l'actionbar (par appui prolongé).

Mais alors, comment faire ? Comment rendre compréhensible ce qui n'est pas intuitif ?

La règle d'or en design reste bien-sûr de subdiviser les tâches, grouper les interactions en ensembles simples, homogènes et faciles à appréhender, et les afficher sur un même écran (règle de regroupement/distinction). Et tout comme il faut faire tester rapidement au cours d'un projet ces interfaces par des utilisateur.trice.s, il est important de tenir compte de leur feedback, leurs impressions. Lorsque vos utilisateur.trice.s ont du mal à comprendre vos écrans, nous vous proposons d'adopter la démarche suivante :

1. Regarder les choses en face

Nous pensons que, dans ces cas-là, il faut prendre acte de l'aspect non-intuitif de notre application. Hors de question donc de faire comme si de rien n'était et de laisser l'utilisateur.trice seul.e, cela aurait d'ailleurs un impact immédiat sur le taux de rétention de l'application.

Il est cependant important de noter que vos utilisateur.trice.s doivent connaître Android, et savoir déjà interagir avec ce téléphone, avoir déjà essayé un certain nombre d'applications. Ne vous laissez pas piéger si on vous dit "ah oui, mais sur iPhone..." : Android existe à part entière et vos utilisateur.trice.s doivent y être familiarisé.e.s, sinon vous risquez de devoir refaire tout le framework Android pour pouvoir ressembler à un iPhone !

2. Recenser les apps similaires et les solutions de design éprouvées

Il est intéressant de faire une veille technologique afin de recenser l'ensemble des applications qui se heurtent au même problème et les solutions imaginées pour y répondre. Vous ne perdrez pas votre temps, loin de là !

Par exemple : nous avons récemment dû implémenter une fonction de déplacement de fichiers dans une de nos applications. Cette fonctionnalité est peu commune et comporte une relative complexité puisqu'il s'agit de prendre un élément depuis un certain contexte (le répertoire souce) et de le déposer dans un second contexte (le répertoire de destination), tout en rappelant l'élément déplacé. Nous avons donc recensé les principaux gestionnaires de fichiers sur Android afin de compiler l'ensemble des méthodes qu'ils proposent pour déplacer un fichier. Au final, nous avons choisi d'adopter un mode de fonctionnement très proche de celui de OI File Manager, que nous aurions eu des difficultés à imaginer.

Les sites Android Patterns et Android UI Patterns sont également de bonnes références pour tout ce qui concerne l'ergonomie sur Android. Ils proposent un nombre important de design patterns pour les interfaces graphiques sur Android et peuvent constituer de bonnes sources d'inspiration lorsque vous séchez.

3. Expliquer la fonctionnalité aux utilisateur/TRICES

Même si la fonctionnalité finit par apparaître naturelle, relativement intuitive, être la mellieure solution, etc. Il est indispensable d'accompagner les utilisateur.trice.s. Malheureusement, il n'existe aucune solution native dans Android permettant de guider l'utilisateur.trice dans la réalisation d'une tâche difficile.

Solutions techniques pour expliquer des UI difficiles

Tutoriel du bureau Android

Si vous vous souvenez, la plateforme Android met en œuvre un processus de ce genre. Par exemple, lors d'une première ouverture de votre bureau sur Android, vous pouvez voir un petit tutoriel vous expliquant comment déplacer une application vers votre bureau. Ci-contre une capture d'écran de ce tutoriel pour vous rappeler votre première installation.

2 solutions open source

Il existe, à notre connaissance, deux librairies permettant d'inclure ce genre de tutoriel dans une application, et elles sont toutes les deux open source :

Ces deux librairies possèdent un repo GitHub contenant une lib et un sample. RoboDemo propose également un apk téléchargeable, ce qui est bien pratique pour tester la lib !

Vous trouverez ci-dessous une brève présentation et un tutorial simple pour chacune de ces deux libs.

ShowcaseView

Capture d'écran de ShowcaseViewShowCaseView propose un layout dérivé de RelativeLayout. Toutes les vues contenues dans ce layout peuvent faire l'objet d'un "showcase" qui a le même look and feel que la démo du bureau Android. Visuellement, la librairie est attractive.

Cette approche est cependant limitée puisqu'elle contraint à utiliser un RelativeLayout. De plus, elle ne permet pas d'expliquer une séquence d'interactions (workflow), mais se limite à un seul élément. La librairie offre cependant une solution pour les tutoriels simples.

Tutoriel rapide de ShowCaseView

Pour finir la présentation de ShowCaseView, nous vous proposons un tutoriel très succinct.

Voici à quoi ressemble le layout.xml d'une Activity que l'on désire illustrer avec ShowCaseView. Ici, nous voulons expliquer le comportement du bouton dont l'id est @id/button :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:showcase="http://schemas.android.com/apk/res-auto" android:orientation="vertical"
              android:layout_width="fill_parent" android:layout_height="fill_parent">
    <FrameLayout android:layout_width="fill_parent" android:layout_height="fill_parent">
        <!-- Le bouton que l'on désire montrer à l'utilisateur.trice -->
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:text="@string/button_hide" android:id="@+id/button" android:layout_marginTop="64dp"
                android:layout_marginLeft="89dp"/>
        <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:text="@string/button_blocked" android:id="@+id/button" android:layout_marginTop="320dp"
                android:layout_marginLeft="89dp"/>
        <com.espian.showcaseview.ShowcaseView android:layout_width="match_parent" android:layout_height="match_parent"
                                              android:id="@+id/showcase" showcase:backgroundColor="#3333B5E5">
            <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
                      android:text="Showcased button" android:id="@+id/textView" style="@style/ShowcaseTitleText"
                      android:layout_marginLeft="6dp" android:layout_marginTop="240dp"/>
            <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
                      android:text="Here's some text explaining the showcased view" android:id="@+id/textView1"
                      android:layout_below="@id/textView" android:layout_alignLeft="@id/textView"
                      style="@style/ShowcaseText"/>
            <Button style="@style/ShowcaseButton" android:text="OK" android:layout_alignParentRight="true"
                    android:layout_alignParentBottom="true" android:layout_marginRight="6dp"
                    android:layout_marginBottom="6dp" android:id="@id/showcase_button"/>
        </com.espian.showcaseview.ShowcaseView>
    </FrameLayout>
</LinearLayout>

Tandis que votre activité va ressembler à ceci :

public class SampleActivity extends Activity 
                implements View.OnClickListener {

	private ShowcaseView sv;
	private Button button;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		button = (Button) findViewById(R.id.button);
		button.setOnClickListener(this);
		sv = (ShowcaseView) findViewById(R.id.showcase);
		sv.setShowcaseView(button);
	}

	@Override
	public void onClick(View view) {
		if (sv.isShown()) {
			sv.hide();
		} else {
			sv.show();
		}
	}
}

Comme on peut le voir la lib est très simple à utiliser dans le code même de l'activité à illustrer. En revanche, le xml est considérablement alourdi par un ensemble de contraintes imposées par la lib.

RoboDemo

Capture d'écran de RoboDemo RoboDemo est une librairie plus complète qui permet de réaliser des tutoriels animés, d'afficher une petite case à cocher pour ne plus rejouer les animations, et elle peut être paramétrée dans de nombreuses directions.

Le fait d'utiliser une animation pour réaliser un tutoriel nous semble plus indiqué pour faire comprendre aux utilisateurs la séquence des manipulations à effectuer dans l'interface. De plus, RoboDemo demande moins de modifications que ShowCaseView dans l'activité à expliquer puisqu'il le tutoriel est présenté dans une autre activité. RoboDemo possède cependant encore quelques limitations, elle n'offre par exemple aucun support pour la gestion des fragments.

Tutoriel rapide de RoboDemo

Pour finir la présentation de RoboDemo, nous vous proposons un tutoriel très succinct.

Tout d'abord, vous devrez créer l'activité qui va afficher le tutoriel. Ces activités doivent créer un DrawViewAdapter, lequel joue le rôle de modèle de données pour l'animation. Cet objet est l'élément grâce auquel RoboDemo peut-être entièrement paramétrée (polices de caractères et couleurs des textes, emplacements, couleurs de l'ombre, etc.). Mais, pour ce tutoriel, gardons les choses simples et utilisons un DefaultDrawViewAdapter fourni par RoboDemo :

public class MainActivityDemoActivity extends DemoActivity {
    @Override
    public DrawViewAdapter getDrawViewAdapter() {
        return new DefaultDrawViewAdapter( this, getListPoints() );
    }
}

Déclarez cette activité dans votre manifeste. N'oubliez pas cette étape. Vous devez porter une attention particulière au thème de votre activité (attribut android:theme) et à faire en sorte que les instances de votre tutoriel ne soit pas inclus dans la Stack des activités (attribut android:nohistory).

<activity
            android:noHistory="true"
            android:name=".MainActivityDemoActivity"
            android:theme="@style/Theme.RoboDemo" />

Et une fois que tout est en place, il ne vous reste plus qu'à modifier l'activité pour laquelle vous souhaitez mettre en place un tutorial. Pour cela, vous devez définir quels sont les composants, ou les points à l'écran que vous voulez inclure dans votre tutoriel. Ces emplacements sont représentés par la classe LabeledPoint. Cette classe possède de nombreux constructeurs pour faciliter le placement des points autour des vues.

Notez également que RoboDemo vous offre un support pour tenir compte de la CheckBox qui permet aux utilisateur.trice.s de supprimer définitivement l'affichage du tutoriel.

private void displayDemoIfNeeded() {

        boolean neverShowDemoAgain = RoboDemo.isNeverShowAgain( this, DEMO_ACTIVITY_ID );

        if ( !neverShowDemoAgain && showDemo ) {
            showDemo = false;
            ArrayList< LabeledPoint > arrayListPoints = new ArrayList< LabeledPoint >();

            // Créer une liste de LabeledPoints qui contiennent des coordonnées et du texte
            //autour d'une vue
            LabeledPoint p = new LabeledPoint( clearButton, getString( R.string.text_move_demo_step_1 ) );
            arrayListPoints.add( p );

            //avec des coordonnées relatives à l'écran pour l'action bar.
            p = new LabeledPoint( this, 0.95f, 0.05f, getString( R.string.text_move_demo_step_2 ) );
            arrayListPoints.add( p );

            // lancer votre DemoActivity.
            Intent intent = new Intent( this, MainActivityDemoActivity.class );
            RoboDemo.prepareDemoActivityIntent( intent, DEMO_ACTIVITY_ID, arrayListPoints );
            startActivity( intent );
        }
    }

Et voilà ! Vous disposez maintenant d'un tutoriel pour votre activité. La mise en œuvre de RoboDemo est certes un peu plus complexe, mais la lib prend de nombreux aspects du tutoriel en charge et vous offre une animaton (paramétrable également).

Conclusion

Cet article nous a permis d'aborder la difficile question des UI qui sortent de la norme. Nous avons vu que, malgré les efforts de Google pour standardiser les interfaces sur Android, et malgré nos efforts en tant que développeur.se.s pour adhérer à ces normes et simplifier les activités, il est toujours possible de rencontrer des écrans "hors normes" et un peu trop compliqués. Dans ces cas, là, ne nous décourageons pas et affrontons le problème. La solution que nous préconisons est d'expliquer les interfaces difficiles aux usager.ère.s. Et pour adresser ces problèmes, il existe notamment des outils que nous pouvons intégrer à nos projets.

On dit de plus en plus souvent « c'est complexe » pour éviter d'expliquer. Ici il faut faire un véritable renversement et montrer que la complexité est un défi que l'esprit doit et peut relever [...]

(Edgar Morin, Éduquer pour l'ère planétaire, p.12, Balland, 2003)