Archives pour la catégorie States

AIR Mobile – Application TweetDeck (4) – Création de la barre du haut (header)

Dans le dernier tutorial, on a créé la barre de navigation qui se trouve en bas de l’application:

AIR Mobile – Application TweetDeck (3) – Ajout de la barre de navigation

Dans cette partie, on va créer la barre qui se trouve en haut. Celle-ci est composé de plusieurs éléments:

  • Un texte central qui indique sur quelle colonne on se trouve (Home, Mentions, …). Lorsque l’on fait défiler les tweets, le texte change et affiche l’heure du tweet affiché en haut de la lise. Lorsque la colonne sur laquelle on est a des updates, le texte est affiché en jaune.
  • Des « pastilles » qui ont 2 états:
    • Un état « gris » qui indique qu’il n’y a pas de nouveaux tweets dans cette colonne
    • Un état « jaune » qui indique que l’utilisateur a de nouveaux tweets à lire

Les pastilles représentent les colonnes qui ne sont pas affichées actuellement à l’écran. Ainsi, s’il on a la première colonne affichée et qu’il reste encore 3 colonnes à droite, 3 pastilles seront présentes à droite de la barre de header. Ces pastilles bougent lorsque l’on navigue entre les listes.

Pour l’instant, on va créer le composant et les pastilles. On verra après pour la « logique métier » et leur déplacement.

Création du composant ColumnHeaderIndicator

On va créer un nouveau composant MXML dans le package « comps » qui va s’appeler ColumnHeaderIndicator, basé sur Group:

Comme pour le composant BottomBar, on va commencer par ajouter un dégradé:

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">
  <s:Rect width="100%" height="100%">
    <s:fill>
      <s:LinearGradient rotation="90">
        <s:GradientEntry color="0x292C29" ratio="0" />
        <s:GradientEntry color="0x525152" ratio="0.2" />
        <s:GradientEntry color="0x313831" ratio="0.8" />
        <s:GradientEntry color="0x212021" ratio="1" />
      </s:LinearGradient>
    </s:fill>
    <s:stroke>
      <s:SolidColorStroke color="0" weight="2" />
    </s:stroke>
  </s:Rect>
</s:Group>

Et on remplace notre composant dans TweetDeckHomeView:

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
        actionBarVisible="false" xmlns:comps="comps.*">
  <s:layout>
    <s:VerticalLayout gap="0" />
  </s:layout>
  <comps:ColumnHeaderIndicator width="100%" height="40" />
  <s:Rect width="100%" height="100%">
    <s:fill>
      <s:SolidColor color="0xFF0FF0" />
    </s:fill>
  </s:Rect>
  <comps:BottomBar width="100%" height="80" />
</s:View>

On teste:

Niveau composant, notre barre va se composer de 2 groupes de pastilles, un à gauche et un à droite. Au milieu, on aura un texte. On aura en fait 2 textes légèrement superposés qui nous permettront de donner un effet d’ombre.

Lire la suite

AIR Mobile – Application Pokémon (31) – Affichage de la progression du téléchargement dans DataPreparationView

Depuis le dernier tutorial, on a une application qui a récupéré ses fonctionnalités mais qui est bien plus légère qu’avant. Si vous reprenez à ce niveau, vous pouvez télécharger le projet tout en bas du dernier tutorial Flex:

AIR Mobile – Application Pokémon (30) – Lecture des images et des mp3 depuis la carte SD

Ce qui fait tâche dans l’application, c’est maintenant cet écran de chargement où il est seulement écrit « Loading… » dans la barre du haut. On va au moins afficher la progression du téléchargement. Cela permettra à l’utilisateur d’estimer le temps qu’il lui reste à attendre.

Déterminer l’avancement de la tâche

Pour déterminer l’avancement du téléchargement, on va utiliser les évènements propagés par FZip. Ainsi, vous avez un ProgressEvent.PROGRESS qui est propagé régulièrement, exposant deux propriétés:

  • bytesLoaded : nombre de bytes téléchargés
  • bytesTotal : nombre de bytes total

Un petit ratio et on obtient notre total de téléchargement.

Dans la partie 28 de ce tutorial, on a déjà ajouté notre handler sur l’évènement ProgressEvent.PROGRESS:

AIR Mobile – Application Pokémon (28) – Téléchargement des images au premier lancement de l’application

Ajoutons donc le calcul de l’avancement:

  protected function onFZipProgress(event:ProgressEvent):void {
	var adv:Number = Math.round((event.bytesLoaded / event.bytesTotal) * 100);
  }

Ajouter une barre de progression

Dans le framework Flex « web », vous avez un composant ProgressBar qui vous permet d’afficher une barre de progression. Cependant, il n’est pas disponible quand vous faîtes un projet Mobile, celui-ci n’étant pas optimisé pour. Mais ce n’est pas grave, on va utiliser un peu notre jugeote.

Dans notre application, on a déjà un composant qui s’apparente plutôt bien à une progress bar, le composant qui affiche les statistiques de notre Pokemon que l’on a finalisé dans la partie 13 de ce fil rouge:

AIR Mobile – Application Pokémon (13) – Affichage des statistiques / Styling du composant

On va donc être « fainéant » et ré-utiliser ce composant pour créer notre barre de progression. Ajoutons notre composant PokemonStat dans notre vue DataPreparationView.mxml:

...
  <s:layout>
    <s:VerticalLayout paddingBottom="15" paddingLeft="15" paddingRight="15" paddingTop="15"
                      horizontalAlign="center" />
  </s:layout>
  <views:PokemonStat id="progressBar" title="Progress..." width="150" />
</s:View>

Et ajoutons le code de mise à jour de la valeur:

  protected function onFZipProgress(event:ProgressEvent):void {
	var adv:Number = Math.round((event.bytesLoaded / event.bytesTotal) * 100);
	progressBar.statValue = adv;
  }

Avant de tester, assurez vous de 2 choses:

  • Supprimez le fichier .nomedia ou commentez la partie qui fait le check de ce fichier onCComplete
  • Cochez la case « Clear application data on each launch » pour éviter de vous faire avoir avec la persistance.

Voici le rendu à 99%:

En plus, en utilisant notre composant, la couleur de la barre de téléchargement évolue, ça donne une effet plutôt sympa :) .

Par contre, une fois que vous avez déjà téléchargé le fichier ZIP, le cache va prendre le relai pour les prochaines tentatives. Le téléchargement ira donc beaucoup trop vite les fois suivantes pour que vous puissiez voir la progression. Si vous voulez tester le rendu de cette progression, testez sur device. Même un redémarrage de Flash Builder n’y fait rien. Sinon, vous pouvez aussi rajouter un paramètre « dummy » à la fin de l »url:

var requester:URLRequest = new URLRequest("http://www.flex-tutorial.fr/wp-content/uploads/pokemon-data.zip?v=1");

Habillage

C’est un peu light pour l’instant, on va rajouter quelques éléments:

  • un petit texte explicatif, avec un léger effet d’ombre portée (un contour offset en fait)
  • un background image répété
  • un dégradé par dessus pour donner un petit effet
  • suppression de la barre d’action en passant actionBarVisible à false

Notez que pour le background image, j’ai utilisé une image provenant de ce site:

http://www.premiumpixels.com/freebies/8-seamless-dark-metal-grid-patterns/

Voici l’image en question (resized à 100×100):

Et voici le résultat!


Lire la suite

Flex 4 – Utilisation de States dans une Skin

Tout d’abord, on va voir l’aspect State. Un composant pouvant être dans plusieurs états différents, il est normal que la Skin suive, et propose plusieurs états. Tout composant héritant de SkinnableComponent a au moins un état, celui de base.
Un composant peut définir des états supplémentaires à l’aide de la balise MetaData [SkinStates]. Voici par exemple les States déclarés dans la classe Button :

  • [SkinState("up")]
  • [SkinState("over")]
  • [SkinState("down")]
  • [SkinState("disabled")]

Pour un bouton, on a quatre States : up, over, down, disabled. On va modifier notre fichier Skin pour avoir un rendu différent dans chaque State. Comme on l’a vu plus haut, on déclare dans une balise « s:states », la liste des States utilisés par le composant :

<s:states>
 <s:State name="up" />
 <s:State name="over" />
 <s:State name="down" />
 <s:State name="disabled" />
 </s:states>

Grâce à cette déclaration, la Skin va respecter sa partie du contrat Skin-Composant. Vous pouvez utiliser la nouvelle notation Flex 4 « pointée ». Ainsi, alpha.disabled= ».5″ indique que l’opacité sera de 0.5 dans l’état nommé « disabled ». Pour donner un effet graphique plus agréable, on va aussi rajouter un léger dégradé.

Voici donc la Skin modifiée pour pouvoir avoir un aspect différent suivant la Skin :

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx" alpha.disabled=".5">

  <s:states>
    <s:State name="up" />
    <s:State name="over" />
    <s:State name="down" />
    <s:State name="disabled" />
  </s:states>

  <s:Rect radiusX="4" radiusY="4" top="0" right="0" bottom="0"
          left="0" includeIn="down">
    <s:fill>
      <s:SolidColor color="0"/>
    </s:fill>
    <s:filters>
      <s:DropShadowFilter knockout="true" blurX="5" blurY="5"
                          alpha="0.32" distance="2" />
    </s:filters>
  </s:Rect>

  <s:Rect id="rect" radiusX="4" radiusY="4" top="0"
          right="0" bottom="0" left="0">
    <s:fill>
      <s:SolidColor color="0x0099FF" color.over="0x0066FF"
                    color.down="0x0000CC"/>
    </s:fill>
    <s:stroke>
      <s:SolidColorStroke color="0x222222" weight="2"/>
    </s:stroke>
  </s:Rect>

  <s:Rect radiusX="4" radiusY="4" top="2" right="2" left="2"
          height="50%">
    <s:fill>
      <s:LinearGradient rotation="90">
        <s:GradientEntry color="0xFFFFFF" alpha=".5"/>
        <s:GradientEntry color="0xFFFFFF" alpha=".1"/>
      </s:LinearGradient>
    </s:fill>
  </s:Rect>

  <s:Label text="Bouton" color="0x222222"
           textAlign="center" verticalAlign="middle"
           horizontalCenter="0" verticalCenter="1"
           left="12" right="12" top="6" bottom="6"
           />
</s:Skin>

Et voici le résultat, dans les différents états :
spark-2

<?xml version= »1.0″ encoding= »utf-8″?>
<s:Skin xmlns:fx= »http://ns.adobe.com/mxml/2009″
xmlns:s= »library://ns.adobe.com/flex/spark »
xmlns:mx= »library://ns.adobe.com/flex/mx » alpha.disabled= ».5″>

<s:states>
<s:State name= »up » />
<s:State name= »over » />
<s:State name= »down » />
<s:State name= »disabled » />
</s:states>

<s:Rect radiusX= »4″ radiusY= »4″ top= »0″ right= »0″ bottom= »0″
left= »0″ includeIn= »down »>
<s:fill>
<s:SolidColor color= »0″/>
</s:fill>
<s:filters>
<s:DropShadowFilter knockout= »true » blurX= »5″ blurY= »5″
alpha= »0.32″ distance= »2″ />
</s:filters>
</s:Rect>

<s:Rect id= »rect » radiusX= »4″ radiusY= »4″ top= »0″
right= »0″ bottom= »0″ left= »0″>
<s:fill>
<s:SolidColor color= »0x0099FF » color.over= »0x0066FF »
color.down= »0x0000CC »/>
</s:fill>
<s:stroke>
<s:SolidColorStroke color= »0×222222″ weight= »2″/>
</s:stroke>
</s:Rect>

<s:Rect radiusX= »4″ radiusY= »4″ top= »2″ right= »2″ left= »2″
height= »50% »>
<s:fill>
<s:LinearGradient rotation= »90″>
<s:GradientEntry color= »0xFFFFFF » alpha= ».5″/>
<s:GradientEntry color= »0xFFFFFF » alpha= ».1″/>
</s:LinearGradient>
</s:fill>
</s:Rect>

<s:Label text= »Bouton » color= »0×222222″
textAlign= »center » verticalAlign= »middle »
horizontalCenter= »0″ verticalCenter= »1″
left= »12″ right= »12″ top= »6″ bottom= »6″
/>
</s:Skin>
Et voici le résultat, dans les différents états :

Flex 4 – (1) Le projet Flex 4 en fil rouge sur flex-tutorial: FTViewer

Adobe Flex 4 est maintenant arrivé à maturité, il est temps de le tester. Il a été en beta pendant plusieurs mois et certains de vous l’ont déjà sûrement testé. Certains l’utilisent même pour leurs applications en production, ce qui est bon signe.

Il est donc venu le temps de laisser Flex 3 de côté (même si je l’utilise toujours et encore pour un moment pour mes devs pro) et de passer à Flex 4 rapidement.

Le projet FTViewer

Et pour apprendre, quoi de mieux que de développer une application. Cela va me permettre d’aborder des problèmes que l’on aborde pas quand on écrit des tutoriaux Adobe Flex restreints. Le but est donc dans les prochaines semaines, d’aborder les nouvelles problématiques Flex 4 en créant une application nommée FTViewer. Celle-ci ne sera pas une application commerciale, mais une application « open source » disponible gratuitement.

Le projet sera déposé sur Google Code, vous pourrez donc le récupérer depuis SVN et consulter les sources directement depuis la page Google Code du projet. Bien sûr, des morceaux de code seront présents au travers des tutoriaux de flex-tutorial.fr, mais la totalité des sources sera sur le repository SVN. Je ne pense pas laisser participer d’autres dev car le projet est uniquement à but d’apprentissage. Si vous souhaitez écrire un article sur flex-tutorial, vous pouvez toujours le faire (plus d’infos).

Tous les articles nommés « Flex 4 – (Numéro) … » feront partie de ce fil rouge applicatif. Toutes les étapes du projet ne sont pour l’instant pas fixées, le projet va aussi évoluer en fonction de mes envies ^^. Il y aura toujours des articles ne concernant pas le projet FTViewer, FTViewer va se faire pendant mon « temps libre ».

Bon alors, le FTViewer, c’est quoi ?

Il nous faut donc une application utilisant au maximum Flex 4. Et pourquoi pas une déclinaison Air 2.0 (qui me branche aussi pas mal). Vous pouvez bien sûr fortement m’influencer dans mon choix qui n’est pas définitif en laissant un commentaire.

Voici donc mon idée pour cette application:

  • Une application n’utilisant aucun framework MVC mais une architecture orientée composant (que je vais expliquer dans la prochaine étape)
  • Une application tournée autour d’un lecteur multimédia avancé utilisant OSMF (nouveauté Flex 4). L’aspect vidéo a été jusque là complètement oublié sur flex-tutorial.fr, il est temps de rattraper cela.
  • Un lecteur multimédia complètement skinné pour aborder les Skins Flex 4
  • L’affichage des miniatures / preview disposées selon différentes mises en page (liste, vignette, carousel iTunes-like, création d’un Layout perso ?…)
  • Gestion de différents thèmes d’interface.
  • Constitution de bibliothèques de lecture
  • Lecture de flux provenant de l’extérieur (Adobe TV ou autres).
  • Peut-être une partie serveur. Un service Java/BlazeDS/Spring/Hibernate/MySQL par exemple pour une gestion de commentaires
  • Support d’autres types de documents multimédia (photos, audio, …)

Avec une déclinaison Adobe Air comprenant les fonctionnalités suivantes:

  • Ajout de vidéos depuis son poste (et encodage?)
  • Gestionnaire de téléchargement de vidéos

Prochain article: Conception d’une architecture orientée composant.

Mettez-y votre grain de sel !

Comme je l’ai dit plus haut, j’attends aussi de voir si cela vous plait (ou pas) ainsi que vos propositions (laissez un commentaire ici) ;)

Flex 4 – Différences entre Flex 3 et Flex 4 (4-Nouvelle syntaxe des States)

Traduction de l’article Differences between Flex 3 and Flex 4 beta de Joan Lafferty.

Flex 4 introduit une nouvelle syntaxe MXML pour les States. Celle-ci est plus « inline », permettant de faire des modifications sur les States en fonction du contexte. Voici les grandes différences de la syntaxe Flex 4 par rapport à Flex 3:

  • Seuls des states sont définis sans le tableau « states »
  • Dans la nouvelle syntaxe des states, vous ne pouvez pas utiliser AddChild ni RemoveChild. A la place, vous devez définissez si un composant fait partie d’un state en utilisant les attributs includeIn et excludeFrom.

Dans l’exemple Flex 3 suivant, les States sont utilisées pour inclure un Button et supprimer un TextInput, seulement quand le « currentState » du document est « submitState ». Cette approche peut être très lourde avec des states complexes:

<mx:states>
    <mx:State name="submitState" basedOn="">
        <mx:AddChild relativeTo="{loginForm}" >
           <mx:Button label="submit" bottom="10" right="10"/>
        </mx:AddChild>
        <mx:RemoveChild target="{firstTextInput}"/>
    </mx:State>
</mx:states>

<mx:TextInput id="firstTextInput" />
<mx:Canvas id="loginForm" />

Voici le même exemple en Flex 4 en utilisant includeIn et excludeFrom:

<s:states>
    <s:State name="submitState" />
</s:states>
<s:TextInput id="firstTextInput" excludeFrom="submitState" />
<s:Group id="loginForm" >
    <s:Button label="submit" bottom="10" right="10" includeIn="submitState"/>
</s:Group>

Les tags SetProperty, SetStyle et SetEventHandler ont été remplacés par la nouvelle syntaxe par point, qui vous permet de préciser un attribut MXML avec un identifiant de State.

Dans le code Flex 3 suivant, le code définit une propriété, un style et un event pour un Button dans l’état submitState:

<mx:states>
    <mx:State name="submitState" basedOn="">
        <mx:SetProperty target="{submitButton}" name="label" value="submit" />
        <mx:SetStyle target="{submitButton}" name="textDecoration" value="underline"/>
        <mx:SetEventHandler target="{submitButton}" name="click" handler="trace('done');"/>
    </mx:State>
    <mx:State name="clearState" basedOn="">
        <mx:SetProperty target="{submitButton}" name="label" value="clear" />
        <mx:SetEventHandler target="{submitButton}" name="click" handler="emptyDocument()" />
    </mx:State>
</mx:states>

<mx:Button id="submitButton" />

Voici à quoi ressemble le même code dans Flex 4:

<s:states>
    <s:State name="submitState" />
    <s:State name="clearState" />
</s:states>

<s:Button label.submitState="submit" textDecoration.submitState="underline"
   click.submitState="trace('done')" click.clearState="emptyDocument()"
   label.clearState="clear" textDecoration.clearState="none"/>

Un composant ne peut plus être dans un état undefined ou null. Par défaut, le premier state déclaré est le State initial du composant. La nouvelle syntaxe est disponible quand vous utiliser le namespace MXML 2009. Vous ne pouvez pas mélanger l’ancienne et la nouvelle syntaxe. L’ancienne syntaxe est uniquement disponible avec le namespace MXML 2006.

Lire la suite