Xamarin & Android Wear (2/3) : L’apparence visuelle en détails

Xamarin Android Wear

Dans mon article précédent, nous avons eu l’occasion de poser les bases nécessaires pour la construction d’une application Android Wear, l’environnement technique, tout en se basant sur un contexte spécifique (la domotique). Je vous propose de continuer sur la création de l’identité visuelle de notre application.

Cet article, pour assurer un maximum de lisibilité a été écrit en 3 parties que nous rappellerons toujours en introduction. S’il s’agit d’un retour d’expérience, c’est aussi un petit guide pour vous aider à bien démarrer sur Android Wear avec Xamarin.

Xamarin & Android Wear (1/3) : Les bases indispensables pour bien démarrer
Xamarin & Android Wear (2/3) : L’apparence visuelle en détails
Xamarin & Android Wear (3/3) : Poser les briques d’une application évoluée

Par où commencer ?

Quand on est habitué à la plateforme Windows (Phone) Store de Microsoft, nous avons une approche logique qui, tout en prônant lisibilité, clarté, fluidité, sobriété, peut ne pas forcément convenir car bien entendu, il faut s’intégrer à la plateforme cible. S’intégrer à la plateforme, cela veut dire, l’appréhender ou tout simplement, la connaître pour satisfaire aux exigences du constructeur (ou sinon, davantage).

Utiliser l’appareil et ses applications

Créer une application à destination d’un appareil impose au moins de le connaître. Et par la suite, savoir l’utiliser, utiliser ses applications. C’est vrai que je ne connaissais que de loin la LG G Watch, et il a fallu quelques temps d’adaptation pour savoir correctement l’utiliser. Comprendre la navigation hiérarchique avec son menu caché tout en haut à droite, comprendre l’utilisation de la voix, son intégration, comprendre la navigation au sein des menus, la navigation au sein des applications, la navigation au sein des notifications, etc… Bref, c’est le minimum pour en avoir une bonne approche, un premier aperçu. Il est vrai que l’on ne pourra pas tester l’intégralité des applications existantes (même si elles ne sont point encore légions), mais, elles peuvent donner un aperçu du potentiel graphique, visuel, ou plutôt de ce qui a été fait. Attention toutefois car, les applications systèmes ne sont pas forcément les plus évoluées visuellement 🙂 sur Android Wear.

Le site développeur pour les designers

Je ne suis pas/plus designer, mais j’aime développer des choses dans l’esprit des plateformes cibles. Rechercher donc chez Google était donc pour moi indispensable. J’avoue avoir été agréablement surpris par ce que j’ai pu trouver sur le site développeurs de Google, non seulement des sections propres aux développeurs, à la distribution des applications, mais aussi au design.

Design des applications Android Wear  : https://developer.android.com/design/wear/index.html .

Si vous désirez pousser un peu plus loin et vous familiariser avec le Material Design, c’est par ici : https://developer.android.com/design/material/index.html

Android Wear Materials

Si vous souhaitez un accès direct aux ressources qui m’ont le plus servies pour ce projet, voici le lien : https://developer.android.com/design/downloads/index.html#Wear

J’ai pu y retrouver :

  • Un guide Toolkit de l’interface utilisateur (UI toolkit) regroupant certaines conventions de nommage, mais aussi des mesures des espaces/positionnements de certains composants de base Android Wear, ainsi que quelques codes couleurs
  • Quelques exemples de pattern de navigation depuis une notification ou une application (Sample user flow patterns), document très pratique pour rapidement voir des cas pratiques qui, même s’ils sont peu nombreux, sont clairs et efficaces.
  • Quelques mocks pour rapidement créer des visuels de son application (Sample app design mocks)

En dessous de cette section “Wear”, il y a une section Style avec le police d’écriture principale (Roboto) et ses bonnes pratiques d’utilisation, ainsi que les couleurs qu’il est possible d’utiliser principalement pour rester au maximum le plus proche de l’identité visuelle idéale.

Quelques manques importants toutefois. Je suis sensible à l’iconographie, vous savez, l’ensemble des ressources graphiques, visuelles pour le marketing de votre application, et ce n’est pas quelque chose que j’ai trouvé sur le site de Google. Il y a cependant une petite section iconographie, une autre relative au branding (votre marque) et quelques conseils d’ordre général dans la section Distribute, spécialement pour tout ce qui est wearable. Ces ressources sont un peu éparses et j’aurai préféré les retrouver dans un seul et même document comme Nathalie a déjà pu le faire via son magnifique Windows Phone DESIGN GUIDELINES cheat sheet. Si ça se trouve, elle nous prépare une surprise aussi de ce côté-là :-).

Contrôles et usages

J’en parlais déjà dans la première partie de ce dossier, Android Wear est une version d’Android spécifique, la version 4.4Wx. Cela veut dire que l’on a un accès à tous les contrôles Android existants et qu’il serait possible de les utiliser. Mais bien entendu, l’usage de certains de ces contrôles ne convient pas toujours car Android Wear se veut optimisé pour ces appareils à faible puissance. Optimisé ne veut pas seulement dire meilleur en terme de performance, mais aussi meilleur en terme d’adaptabilité et d’usage pour l’appareil ou le système hôte. Si quelques contrôles se prêtent donc bien à ce jeu de compatibilité comme les labels (TextView), images (ImageView), ou encore les boutons (Button), d’autres ne sont tous simplement pas adaptés, ni même compatibles comme l’ActionBar, ou les sélecteurs comme les Spinners, les layouts comme les ListView, GridView, etc… Cela signifie qu’il risque d’y avoir plus d’efforts à fournir pour obtenir un résultat visuel intéressant. Google semble ici vouloir pousser l’utilisation d’autres contrôles spécifiques que nous verrons ensemble.

Les layouts

Les layouts définissent la structure visuelle pour une interface utilisateur. Une problématique importante quand on développe pour Android Wear est qu’il y a 2 facteurs de formes à cibler, les appareils à forme carré et à forme ronde. Si donc les habituels LinearLayout et RelativeLayout sont toujours utilisés, de nouveaux contrôles apparaissent afin d’aider à mieux décrire les apparences de vos applications et gérer ces 2 formes. Et c’est une nécessité, au risque de se retrouver avec une apparence pouvant ressembler à ça :
Wear Square Round Default Layout

Bon, je l’admets, j’ai volontairement fait en sorte que ça ne fonctionne pas sur les 2 types d’écrans :-), mais ça fonctionnait par défaut.

Gestion du layout “manuelle” avec le WatchViewStub

Si nous avions été habitués aux qualificatifs suffixés de type layout-sw600dp pour la gestion de différents types d’écran, la gestion des vues ciblant les différents types d’appareil peut être faite avec le contrôle WatchViewStub. Ce contrôle permet pour une vue spécifique, de préciser via 2 attributs, rectLayout et roundLayout, les chemins relatifs aux vues pour la forme carré, et une autre pour la forme ronde. Cela se gère simplement comme ceci :

<android.support.wearable.view.WatchViewStub
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="@layout/rect_main_activity_wear"
app:roundLayout="@layout/round_main_activity_wear">
</android.support.wearable.view.WatchViewStub>

Libre aux développeurs (ou intégrateurs) de créer des vues spécifiques pour chaque forme et de les lier à la vue principale avec le WatchViewStub.

Voici un exemple de rendu avec ce contrôle :

Wear Square Round Watchviewstub Layout

On peut remarquer au premier coup d’œil que selon l’écran, le visuel est adapté. (Bien entendu, cela dépendra aussi de la façon dont le visuel est géré, si les éléments visuels s’adaptent au parent ou pas), si des attributs de tailles fixes ne sont également pas utilisés.

Il existe une autre façon de procéder, utiliser un autre contrôle mais qui offre d’autres possibilités, c’est le BoxInsetLayout.

BoxInsetLayout

Si l’on utilise le même layout que ceux que j’ai utilisé précédemment avec le BoxInsetLayout, le rendu sera strictement le même. Voici un exemple de code montrant comment l’utiliser :

<android.support.wearable.view.BoxInsetLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/dual_sided_bird_thermometer"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:padding="10dp">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp"
        app:layout_box="all">

     // YOUR UI CODE

</FrameLayout>
</android.support.wearable.view.BoxInsetLayout>

Mais quel intérêt d’utiliser l’un ou autre ? Notre contrôle a ici un attribut layout_box, qui rajoute une possibilité supplémentaire, celle de prendre en compte une zone de fenêtre fixe. L’intérêt réel est de forcer un affichage identique, et ce, peu importe le facteur de forme. Je peux vouloir par exemple que ma zone d’affichage reste coûte que coûte carré. C’est ainsi tout l’intérêt de ce contrôle.

Wear Square Round Boxinset Layout

 

C’est vrai que l’affichage n’est pas adapté à notre écran, mais, le rendu visuel est contenu dans un carré avec une marge extérieure. Tout cela est rendu possible grâce en partie à l’attribut layout_box qui permettra d’influer sur la façon dont les éléments enfants sont positionnés dans la zone fenêtrée. Pour en savoir plus, vous pouvez lire la documentation sur le sujet présentant son utilisation.

La gestion des listes

Durant mon projet, ça a été un point assez sensible et bloquant que je n’ai pas réussi à résoudre. Le SDK Android Wear embarque un contrôle optimisé pour les périphériques portables, le WearableListView. Si son utilisation semble simple, il n’a malheureusement pas été possible pour moi de l’utiliser pendant mon projet. Et pour cause, son support est mal assuré dans le SDK Wearable créé par Xamarin. J’ai remonté ce problème il y a quelques temps, et il n’y a pas encore de nouvelles versions du sdk proposant un bug fix (en fait, une nouvelle version est sortie, mais je ne l’ai pas encore testée), mais un workaround récent que je n’ai pas eu l’occasion de tester. Dès qu’il sera possible de l’utiliser de façon officielle, je reviendrai sans aucun doute là-dessus. Je pouvais me rabattre sur les ListView classiques, mais cela me demanderait trop d’efforts sur l’optimisation (tactile, visuelle, etc…).

Les cards

Bien qu’elle ne soit plus très récente, la notion de card avait été complètement nouvelle pour moi, même si j’en avais déjà vu quelques visuels. En termes très simple, une card est un containeur visuel avec un titre, une description et éventuellement, une icône. Ce container a une apparence particulière par défaut, c’est un rectangle de fond blanc avec des bords arrondis, une légère bordure et une légère ombre. L’avantage de ce conteneur est qu’il ne demande aucun style particulier et fourni déjà les éléments nécessaires à sa constitution.

Wear card samples

Pour les intégrer à vos layouts, il y a 2 façons de procéder.

La première consiste à passer par le code C#, dans le code behind de votre vue, et créer une instance de l’objet CardFragment (ou en passant par la méthode statique de l’objet CardFragment).


CardFragment.Create("Greetings", "Hello World!", Resource.Drawable.Icon);

La seconde méthode est d’utiliser dans vos layouts le contrôle CardFrame :

<android.support.wearable.view.BoxInsetLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@drawable/dual_sided_bird_thermometer"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

    <android.support.wearable.view.CardScrollView
        android:id="@+id/card_scroll_view"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        app:layout_box="all">

        <android.support.wearable.view.CardFrame
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            android:layout_gravity="bottom">

            <LinearLayout
                android:layout_height="wrap_content"
                android:layout_width="fill_parent"
                android:orientation="vertical">

                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="Welcome"
                    android:textSize="26dp"
                    android:fontFamily="sans-serif-bold"
                    android:layout_gravity="center|center_horizontal|center_vertical"
                    android:gravity="center|center_vertical|center_horizontal"/>

                <TextView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:text="Press the magic button"
                    android:textSize="18dp"
                    android:fontFamily="sans-serif-light"
                    android:padding="5dp"
                    android:layout_gravity="center|center_horizontal|center_vertical"
                    android:gravity="center|center_vertical|center_horizontal"/>

                <Button
                    android:id="@+id/runSpeechRButton"
                    android:layout_width="70dp"
                    android:layout_height="70dp"
                    android:background="@drawable/mic_icon"
                    android:layout_gravity="center_horizontal|center_vertical" />
            </LinearLayout>
        </android.support.wearable.view.CardFrame>
    </android.support.wearable.view.CardScrollView>
</android.support.wearable.view.BoxInsetLayout>

Quand utiliser l’une ou l’autre solution ?

Si vous souhaitez créer une card personnalisée, alors, utiliser l’option CardFrame est préférable. Autrement, via le code C#, ce sera suffisant.

Pour en savoir plus, je vous invite à consulter la documentation en ligne sur la création des Cards pour Android Wear.

Navigation alternative avec le 2D Picker

Quand on utilise Android Wear et que vous synchronisez votre montre avec votre téléphone ou votre tablette, il est fort probable que vous y receviez des notifications. Et il est possible d’interagir avec ces notifications via un système de navigation que l’on appelle le pattern 2D Picker. Ce pattern qui s’utilise avec un contrôle spécifique, le GridViewPager permet de créer une liste de listes de pages (des CardFragments).

Il y a des recommandations quant à la façon de naviguer vers les différentes options (pages) que vous avez créés, et il est indispensable de les consulter. Au risque de perdre l’utilisateur dans une navigation à laquelle il ne serait pas familier.

Son utilisation reste très simple :

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#fafafa"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <android.support.wearable.view.GridViewPager
        android:id="@+id/gvPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

Toutefois, avec Xamarin (mais à cause du SDK Google cette fois-ci)…. il y a un bug assez sérieux empêchant d’utiliser correctement le GridViewPager lors que l’on assigne son adapteur (bug que j’avais pris le soin de signaler). Le GridViewPager a besoin d’une liste d’éléments fourni à son adapteur pour fonctionner. Le problème était que, au moment d’instancier l’adapter de façon classique à la création de la vue, une erreur était générée. Un workaround m’a été suggéré en quelques étapes :

  1. Changer la visibilité du GridViewPager par défaut à gone (afin qu’il n’existe pas dans l’arbre visuel)
  2. Créer son instance dans l’évènement OnCreate de la vue
  3. Lors de l’évènement OnStart, instancier l’adapteur
  4. Changer la visibilité du GridViewPager à Visible.

Cela nécessite quelques efforts supplémentaires, mais a le mérite de fonctionner en attendant que Google puis Xamarin fassent les mises à jour nécessaires.

La création des options du contrôle a été un peu fastidieuse je dois avouer. Nous y reviendrons dans le prochain article sur la conception de notre application.

Les confirmations

Avec Android Wear, il y a des comportements ou des contrôles que l’on appelle Confirmation. Ces contrôles peuvent utiliser l’intégralité de l’écran de l’appareil ou une portion et permettent à l’utilisateur d’avoir une surface suffisamment grande pour interagir avec l’application pour une action particulière. On retrouvera 2 notions de confirmations : les confirmations chronométrées (confirmation timers) et les confirmations animées (confirmation animations). La documentation officielle est assez claire sur le sujet et sur leur utilisation, et le code est facilement adaptable à Xamarin. Je vous propose d’y revenir dans notre prochain article.

Et l’application du contexte ?

L’application n’était pas difficile en soit, sauf pour la partie visuelle bien entendu. J’avais plusieurs fonctionnalités, plusieurs écrans auxquels je souhaitais accéder. Dans un premier temps, j’ai suggéré l’utilisation des commandes vocales (pratiques mais insuffisantes en milieu événementiel ou l’on peut se retrouver avec beaucoup de bruits d’ambiance). L’impossibilité d’utiliser une simple liste comme la WearListView m’a obligé à créer un menu simple devenu complexe avec le GridViewPager mais qui a fait l’affaire finalement.

Conclusion

Voilà, nous avons pu faire le tour en bref de ce qu’il faut savoir pour pouvoir concevoir notre application visuellement. Certaines choses peuvent vous faire perdre un peu de temps, c’est ce que nous avons évoqués ici avec notamment les listes ou le 2D Picker. Il existe cependant des solutions pour parvenir à nos fins. C’est donc maintenant que la partie la plus intéressante pour les développeurs débute :-), celle qui nous permet de rentrer dans le cœur du sujet, la construction des briques importantes de notre application Android Wear.

Nombre de vue : 129

COMMENTAIRES 2 commentaires

  1. […] la suite : Xamarin & Android Wear (2/3) : L’apparence visuelle en détails David POULIN (20 […]

  2. Avec l’explosion du marché concerné en 2014, cet article est on ne peut plus pertinent. J’attends la suite avec impatience 🙂

AJOUTER UN COMMENTAIRE