AIR Mobile – Application Pokémon (13) – Affichage des statistiques / Styling du composant
Dans notre dernier tutorial, on a vu comment utiliser notre composant PokemonStat dans notre application:
Le rendu est assez bon, mais on va faire mieux en modifiant la couleur et la taille de la barre en fonction de la valeur de la statistique affichée.
Modification de la taille de la barre
Première étape, la plus simple, la modification de la taille de la barre. Celle-ci est déterminée par les primitives "Rect" de PokemonStat qui sont pour l'instant définies à 100%. La largeur de la barre doit donc être proportionnelle à la valeur passée à la propriété "statValue". Celle-ci est comprise entre 15 et 130 pour les meilleurs Pokémons. Pour faire simple, on va faire un Binding (liaison dynamique) entre la propriété "width" des Rect et la valeur de "statValue" multipliée par 1.5:
...
<s:Group width="100%" height="70">
<s:Rect width="{statValue * 1.5}" height="100%">
<s:fill>
<s:SolidColor color="{_colorValue}" />
</s:fill>
<s:stroke>
<s:SolidColorStroke color="0x3E3E3E" weight="2" />
</s:stroke>
</s:Rect>
<s:Rect width="{statValue * 1.5}" height="100%">
...
Le coefficient 1.5 est totalement arbitraire. Ce n'est pas vraiment adapté si vous avez un écran de grande taille (une tablette par exemple) mais on y reviendra plus tard. Voici le rendu à ce niveau:
Modification de la couleur
Pour modifier la couleur, on va utiliser des paliers de couleurs. Si le couleur se situe dans un certain intervalle, une couleur arbitraire lui sera attribuée (du rouge au vert). Ici, on ne va pas faire de Binding mais on va utiliser une autre technique. En effet, on a besoin de déterminer la couleur que lorsque l'on affecte une valeur à la propriété "statValue". Mais on n'appelle jamais une fonction pour affecter cette valeur, tout se fait par Binding.
Pour pouvoir intercepter cette affectation, on va créer un getter et un setter sur statValue. Ces méthodes vont permettre de rendre notre propriété "statValue" private. Toute affectation ou récupération de valeur se fera par le setter et le getter respectivement.
AIR Mobile – Application Pokémon (12) – Affichage des statistiques / Utilisation du composant PokemonStat
Dans le dernier tutorial, on a encapsulé notre barre de statistique dans un composant autonome:
AIR Mobile – Application Pokémon (11) – Affichage des statistiques / Création d'un composant
Au final, vous vous êtes retrouvé avec exactement le même rendu, sauf que vous aviez un composant. On va voir dans cette partie comment utiliser ce composant pour afficher les 6 statistiques de notre Pokémon.
Ajout des 6 composants PokemonStat
Dans la vue PokemonDetailsView, ajoutez 6 fois le composant PokemonStat en liant chaque composant à une propriété de votre objet Pokemon:
...
<s:Image id="img" />
<views:PokemonStat title="Vie" statValue="{_p.pv}" />
<views:PokemonStat title="Vitesse" statValue="{_p.vit}" />
<views:PokemonStat title="Attaque" statValue="{_p.atk}" />
<views:PokemonStat title="Défense" statValue="{_p.def}" />
<views:PokemonStat title="Attaque Spé." statValue="{_p.atkspe}" />
<views:PokemonStat title="Défense Spé." statValue="{_p.defspe}" />
</s:View>
...
Lancez votre application et vous obtenez:
…Hum, ce n'est pas vraiment le résultat que l'on espérait obtenir. Les composants sont en fait empilés les un au dessus des autres. Pourquoi? Car le composant qui les contient (View) est basé sur Group, qui est un composant qui ne donne aucune contrainte de base à ses enfants.
Modification du layout de la View
Pour y voir plus clair, on va mettre une mise en page verticale. Pour cela, on va préciser la propriété "layout" de notre vue. Cela peut être fait directement dans le MXML. On va assigner à cette propriété, un objet de type VerticalLayout:
... </fx:Script> <s:layout> <s:VerticalLayout /> </s:layout> <s:Image id="img" /> ...
Relancez votre application, voilà le résultat:
C'est déjà mieux. Mais vous pouvez constater que l'on réserve beaucoup de place pour chaque statistique. On pourrait en rentrer 2 par lignes sans problème. C'est ce que nous allons faire.
AIR Mobile – Application Pokémon (11) – Affichage des statistiques / Création d'un composant
Dans le dernier tutorial, on a vu comment afficher une barre de statistiques dans notre application:
AIR Mobile – Application Pokémon (10) – Affichage des statistiques / Création de primitives
On a fait cela directement dans la vue pour le moment, pour s'entraîner. Sauf que par la suite, on va afficher plusieurs statistiques (attaque, défense, …). Comme on a pas envie de recopier ce code N fois, cela nous donne une bonne occasion pour créer un composant.
Vous avez déjà utilisé certains des composants disponibles dans le framework Flex (Image, View, Label, …). Ici, vous allez créer votre propre composant que vous allez ré-utiliser dans votre application. Cette pratique vous permet de factoriser le code afin de faciliter sa maintenance. Un peu comme lorsque l'on place un code répété plusieurs fois dans une fonction.
Création du composant
Rendez-vous dans la vue Package Explorer et sur le package "views", faites un click droit > New > MXML Component:
Donnez lui le nom "PokemonStat". De base, pour un projet mobile, Flex remplit par défaut la valeur de "Based on" avec la classe View, ce qui vous permet de créer rapidement de nouvelles vues. Dans notre cas, on ne veut pas réaliser une nouvelle vue mais un composant que l'on va incorporer à notre View. Cliquez sur "Browse…". Une nouvelle fenêtre va s'ouvrir vous permettant de choisir la classe de base de ce composant. Dans notre cas, on va se baser sur VGroup. En effet, rappelez-vous de l'étape précédente, tous nos composants étaient encapsulés dans un conteneur de type VGroup.
Tapez "vg" pour que Flex vous suggère VGroup dans la liste et choisissez-là. Supprimez les valeurs de width / height par défaut:
Un nouveau fichier avec un squelette de code vient d'être créé pour vous:
<?xml version="1.0" encoding="utf-8"?>
<s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:VGroup>
On va maintenant utiliser notre "esquisse" de composant que l'on a créé à l'étape 10 pour créer notre composant. N'oubliez pas le width="100%" à rajouter dans le tag racine:
<?xml version="1.0" encoding="utf-8"?>
<s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" width="100%">
<s:Label text="Attaque" color="white" />
<s:Group width="100%" height="70">
<s:Rect width="100%" height="100%">
<s:fill>
<s:SolidColor color="0xFF0000" />
</s:fill>
<s:stroke>
<s:SolidColorStroke color="0x3E3E3E" weight="2" />
</s:stroke>
</s:Rect>
<s:Rect width="100%" height="100%">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0x000000" alpha="0" />
<s:GradientEntry color="0x000000" alpha="0.4" ratio=".66" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<s:Label fontSize="60" fontWeight="bold" color="0xEEEEEE" text="{_p.atk}" left="5"
verticalCenter="0">
<s:filters>
<s:DropShadowFilter distance="1" angle="-90" color="0" blurX="0" blurY="0" />
</s:filters>
</s:Label>
</s:Group>
</s:VGroup>
Si vous sauvegardez, vous n'obtiendrez aucune erreur. Pourtant, dans ce composant, nous référençons {_p.atk} qui ne correspond à rien dans ce contexte (dans le scope du composant). En fait, aucune erreur n'est générée car le composant n'est pas utilisé dans votre application. Il n'est donc pas compilé et le compilateur ne vous dira rien.











