Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS, MAUI

La révolution des contrôles unifiés (en kit pour l’instant), un pas vers l’universalité des UI !

Le prochain saut vers MAUI fait fantasmer d’un ensemble de contrôles totalement XAML et identiques sur toutes les plateformes, les derniers ajouts aux Xamarin.Forms permettent déjà de donner consistance à ce rêve…

Contrôles et look natifs : Une doctrine sans suite

avertissement : longue intro. Ceux qui veulent manger du code tout de suite peuvent la sauter, ceux qui veulent comprendre les enjeux gigantesques qui se cachent derrière tout ça peuvent continuer à la ligne suivante !

Dès le départ le combat fut rude entre les protagonistes qui souhaitaient dominer le monde du mobile avec leurs OS respectifs. Parmi leurs armes favorites : un look “unique” forcément plus cool et plus facile à utiliser que celui des concurrents. On ne parlera alors plus d’UI mais de la plus branchée “UX”, la fameuse “expérience utilisateur” comme si appeler sa grand-mère avec son téléphone mobile faisait de vous un savant expérimentant une technologie de ouf…

Bref passons sur la rhétorique de tous ces marchands de lendemain qui chantent juste en leur demandant poliment. Hey Google, passe-moi le dernier David Guetta ! Hey Siri, est-ce qu’il va pleuvoir ? Faisant de nous des larves décérébrées incapables de regarder à la fenêtre pour voir s’il fait beau ou pas, et ne se rendant pas compte qu’il a fallu payer, outre la machine, un abonnement data s’ajoutant à un service de musique en ligne payant au lieu de brancher gratuitement une radio FM, surtout pour écouter les mêmes médiocrités…

Le progrès ne se discute pas n’est-ce pas… Le libéralisme et le consumériste si, mais c’est un autre sujet. Revenons à la bataille opposant nos champions.

Chacun pensant gagner et le souhaitant ardemment, surtout les investisseurs se tenant derrière, il fallait inventer quelque chose qui ne tombe pas sous le coup des lois mais qui rende captif tout de même futurs clients et développeurs. Cette arme est déjà connue de tous les rois de l’obsolescence programmée, c’est le design. L’obsolescence par le design est l’une des façons de forcer la consommation sans même avoir à dégrader la qualité des produits, l’utilisateurs jettera de lui-même un produit qui marche encore juste parce qu’on lui aura donné envie d’un nouveau design, c’est diabolique. Mais le design peut être utilisé aussi pour rendre l’utilisateur captif, et ainsi rendre tout aussi captif les développeurs.

C’est ainsi que chacun créa un look différent, une UX supposée révolutionnaire mais surtout différente de celle du voisin ! Ainsi l’utilisateur Apple sera perdu sur un Android et un amoureux des tuiles de Microsoft sera totalement déboussolé par le bouton unique de Apple, etc. Créant aussi des clans s’opposant, une fantastique caisse de résonnance pour bâtir une “communauté” qui se chargera gratuitement d’une partie du travail de propagande sur les réseaux sociaux ! Cette idée date des fabricants de lessive, pas de quoi crier au génie de certains faux gourous… Combien de ménagères de moins de 50 ans se sont étripées parce qu’Ariel lavait plus blanc (ou pas) que Bonux… Alors que souvent les marques en questions appartenaient au final aux mêmes groupes ou contenaient au final les mêmes composés colorés un coup en rouge pour l’un, en bleu pour l’autre !

C’est ainsi que le respect du dress code, enfin de l’UI maison portant un nom super disruptif et évocateur, fut imposé comme une loi sacrée. “Tu n’utiliseras pas de look Android sur Apple” (et réciproquement), les nouveaux prophètes avaient parlé façon péplum biblique, dieu lui-même venant graver dans le marbre les mots de cette nouvelle Table de la Loi donnée aux Hommes. La punition divine étant le rejet de l’App (le mot programme ne faisait plus assez cool) dans le “Store” (le magasin quoi…). Punition ultime privant le développeur de substantiels revenus (fantasmés pour une majorité qui malgré tout doit payer sa dîme pour avoir le droit de publier son œuvre…).

Le célèbre divide ut reges (diviser pour régner) popularisé chez nous par Machiavel dans son ouvrage “Le Prince” sous la forme divide et impera, (divise et règne !) est une vieille recette qui marche toujours.

C’est ainsi que les boutons (et le reste) ayant pourtant une même fonction prirent des looks et des astuces de manipulation différents sur iOS, Android et Windows Phone, parfois ronds, parfois carrés, skeuomorphisme imposé ici et ailleurs surtout pas !

Pour le développeur cross-plateforme l’enfer avait commencé. Déjà la guerre des langages et des EDI n’était pas prête de s’éteindre mais en plus, fait nouveau, la guerre des UI/UX allaient rendre la conception de la moindre App un casse-tête couteux… De quoi décider certains à se spécialiser sur une plate-forme et à abandonner les autres, but recherché par nos futurs ou ex champions, comme au bon vieux temps où il fallait choisir de développer pour Mac ou pour PC.

Mais voilà, les utilisateurs se paument en changeant de machine, ce qui leur est parfois imposé par le travail, les entreprises elles-mêmes voient leur service d’assistance exploser au rythme des spécialistes de chaque plateforme qu’il faut engager pour répondre aux mêmes questions mais qui réclament des réponses adaptées et différentes !

C’est ainsi qu’une époque se termine, laminée par sa propre bêtise, anéantie par sa propre envie d’anéantir l’autre.

Car des voix de plus en plus nombreuses, hier inaudibles, se font de plus en plus entendre pour réclamer des UI non pas toutes semblables, chaque développeur, chaque entreprise désirant conserver son “branding”, mais identiques sur toutes les plateformes pour un produit donné.

Hors cela n’est pas très difficile à concevoir… Microsoft avec Silverlight avait prouvé il y a longtemps qu’on pouvait écrire le même code XAML et C# pour des applications Web s’exécutant de la même façon sur un PC et un Mac pourtant jugés irréconciliables…

Pourquoi alors ne pas rendre le vieux rêve de WPF/E, WPF Everywhere, plus connu sous le nom de Silverlight, enfin une réalité moderne ? !

En introduisant les Paths et les Shapes ainsi que les Brushes et autres artifices du “vrai” XAML de WPF dans les Xamarin.Forms pour faciliter leur transformation en MAUI, Microsoft a rendu ce vieux rêve avorté sous Silverlight tout à fait réalisable sous Xamarin.Forms dès aujourd’hui et plus encore demain sous MAUI !

Il ne manque techniquement que peu de choses alors pour retrouver toute la puissance du templating des contrôles de WPF, et la liberté de designer les contrôles d’une App comme on le désire, tout en restant en XAML et sans jamais avoir à écrire de “renderer” ou du “code natif” dont tout le monde se fiche complètement. Un XAML, une App, et c’est tout.

Pourquoi pas alors un jeux de contrôles entièrement graphiques pour MAUI façon WPF ?

De ce que j’ai entendu certains chez Microsoft ne seraient pas chaud, voire s’opposeraient à ce qui semble un avènement pourtant inévitable. Il y a des dinosaures partout hélas. Mais même si MS n’allait pas dans ce sens, en nous donnant les outils pour le faire nul doute qu’une communauté ou une autre s’en chargera rapidement ! La machine est lancée, l’idée taraude plus d’un cerveau, la technique est prête, personne n’arrêtera le train du progrès. Chez l’humain on sait que “Si c’est possible ça sera fait”. Et justement, c’est possible !

Et c’est ce que je vais vous prouver aujourd’hui non pas sous MAUI mais avec les Xamarin.Forms et grâce à leurs derniers ajouts graphiques…

Derrière le simple geste technique du développeur auquel nous allons passer maintenant se cache ainsi une histoire, une évolution, et une envie motivée par des raisons légitimes. Dommage pour ceux qui auront sauté l’intro  Smile

Un contrôle à bascule totalement graphique

Ah vous voilà ! Ceux qui ont sauté l’intro viennent d’arriver alors passons au vif du sujet !

L’objectif

Il est évident pour ceux qui ont lu l’intro mais précisons-le : utiliser les derniers ajouts graphiques des Xamarin.Forms pour concevoir un contrôle qui s’affichera à l’identique sous tous les OS supportés et ce en n’utilisant uniquement que C# et XAML donc sans jamais toucher aux projets natifs ni écrire le moindre renderer.

Notre cible

C’est une démo, un POC, choisissons quelque chose d’assez ambitieux pour être fonctionnel mais d’assez simple pour ne pas réclamer cent pages de code : un bouton à bascule. dont voici une ébauche sous Inkscape :

image

Rien de compliqué puisque c’est le principe qui compte. Une sorte de gélule contient une bille qui se trouvera soit à gauche soit à droite.

Comportement

L’objet devra supporter le Tap pour changer d’état, On ou Off. Disons qu’il nous faut aussi deux états visuels distincts selon l’idée suivante :

image

En haut la position “Off” avec la boule grisée, en bas la position “On” avec la boule colorée.

On souhaitera aussi que les couleurs soient personnalisables facilement notamment via des propriétés XAML supportant le binding. L’état On/Off du bouton devra pouvoir être manipulé depuis le programme mais le bouton pourra lui aussi émettre un changement d’état suivant le Tap de l’utilisateur.

Conception graphique

Nous ne disposons pas encore d’une intégration des Xamarin.Forms (ou de MAUI) dans Blend, fantastique outil de conception vectorielle pour XAML. Ce n’est pas grave ici, les données graphiques qui nous intéressent doivent juste être compatible SVG. Un logiciel gratuit comme Inkscape travaille dans ce mode mais on pourra utiliser Corel Draw ou Illustrator si on dispose de ces applications.

Premier essai

Pour ne pas tout mélanger il faut simplifier. Notre contrôle sera ainsi un descendant de AbsoluteLayout, il ne supportera pas de redimensionnement automatique c’est vrai mais ce n’est qu’un début faut-il le rappeler !

Pour se faire je vais ajouter un répertoire “Controls” à mon projet Xamarin.Forms puis ajouter un élément de type page de contenu appelé BasculeXAML. Pourquoi une page de contenu ? Parce que VS ne donne pas le choix de partir de n’importe quel contrôle. Une fois le fichier créé (C# + XAML) je vais donc m’empresser de changer le type ContentPage en AbsoluteLayout… Un peu enquiquinant mais c’est assez rapide à faire.

Ensuite je vais récupérer dans Inkscape les données qui correspondent au dessin de la “gélule”. Je vous ai déjà montré dans un article précédent comme effectuer cette manipulation. Avec ses données SVG (comprises par XAML) je vais créer une forme constituée de la gélule et d’une ellipse pour faire le point.

Cela va nous donner le code suivant côté XAML :

<?xml version="1.0" encoding="UTF-8" ?>
<AbsoluteLayout
    x:Class="FormsIcons.Views.TechieSwitch"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <AbsoluteLayout.GestureRecognizers>
        <TapGestureRecognizer Tapped="ClickGestureRecognizer_OnClicked" />
    </AbsoluteLayout.GestureRecognizers>
    <Path
        x:Name="Border"
        Aspect="Fill"
        Data="M9.53 0l18.44 0c2.62,0 5,1.07 6.73,2.8 1.73,1.73 2.8,4.11 2.8,6.73 0,2.62 -1.07,5 -2.8,6.73 -1.73,1.73 -4.11,2.8 -6.73,2.8l-18.44 0c-2.62,0 -5,-1.07 -6.73,-2.8 -1.73,-1.73 -2.8,-4.11 -2.8,-6.73 0,-2.62 1.07,-5.01 2.8,-6.73 1.73,-1.73 4.11,-2.8 6.73,-2.8zm18.44 1.13l-18.44 0c-2.31,0 -4.41,0.95 -5.93,2.47 -1.52,1.52 -2.47,3.62 -2.47,5.93 0,2.31 0.95,4.41 2.47,5.93 1.52,1.52 3.62,2.47 5.93,2.47l18.44 0c2.31,0 4.41,-0.95 5.93,-2.47 1.52,-1.52 2.47,-3.62 2.47,-5.93 0,-2.31 -0.95,-4.41 -2.47,-5.93 -1.52,-1.52 -3.62,-2.47 -5.93,-2.47z"
        Fill="#0079e2"
        HeightRequest="20"
        WidthRequest="38" />
    <Ellipse
        x:Name="Thumb"
        x:FieldModifier="private"
        AbsoluteLayout.LayoutBounds="2,2,16,16"
        Fill="#0079e2"
        HeightRequest="16"
        WidthRequest="16" />

</AbsoluteLayout>

Version fonctionnelle

Vous avez compris l’esprit de l’essai ci-dessus. C’est une base de réflexion, maintenant nous allons tenter de rendre tout cela vraiment fonctionnel en copiant une idée d’UI assez jolie utilisant justement le type de bouton que nous sommes en train de créer :

image

L’idée sera de refaire cette interface en y intégrant notre bouton, l’UI est une idée de Manoj Rajput pour un système de Smart Home, vous trouverez l’image sur Dribbble en cliquant sur la capture ci-dessus.

Le résultat visuel de notre prototype sera le suivant :

BasculeButton


Comme on on peut le constater c’est assez ressemblant et surtout notre contrôle fonctionne à merveille !

Le Code

Le code final serait un peu long à publier in extenso ici et peu pratique à tester, c’est pourquoi je vous ai fait un zip de la solution que vous trouverez à l’adresse suivante avec les autres sources de Dot.Blog que je publie (c’est un lien Dropbox vers le dossier que je partage, gardez l’adresse pour une autre fois !). Le fichier qui nous intéresse ici s’appelle BasculeButton.zip.

Le répertoire se trouve ici : https://www.dropbox.com/sh/0n1whngngn15lps/AABGZaMDOHerCf-7EkkHW6w-a?dl=0

Conclusion

Je ne vais pas refaire l’introduction, ne vous inquiétez pas Smile mais au-delà de la petite prouesse de créer un composant graphique qui sera identique sur toutes les plateformes uniquement en C#/XAML des Xamarin.Forms vous comprenez bien, j’en suis certain, toute la portée pour l’avenir de MAUI.

Disposer d’une telle bibliothèque reprenant tous les contrôles de base mais totalement et uniquement en C#/XAML sans aucun renderer et proposant un look absolument identique partout, c’est un tournant de l’histoire. Que Microsoft appuie ce virage ou non n’a plus d’importance, c’est possible à faire, cela sera fait, par eux ou un groupe quelconque en Open Source.

Xamarin.Forms comme MAUI savent et sauront toujours faire appel à des contrôles natifs, mais désormais la porte est ouverte à une UI cross-plateforme totalement unifiée. Une entreprise pourra ainsi disposer d’Apps qui se présenteront de la même façon sur Android ou iOS, simplifiant la maintenance des logiciels mais allégeant aussi le travail des services d’assistance.

Tout le monde a quelque chose à y gagner, ce n’est pas un choix exclusif, c’est une possibilité de plus, et cette approche a plus d’un atout pour séduire.

L’avenir sera passionnant comme d’habitude. Donc…

Stay Tuned !

blog comments powered by Disqus