Apache Adobe Flex TutorialTutoriaux Adobe Flex & AIR en Français

27août/101

Hero – Le premier build de Flex 4.5 dévoilé

J'en parlais il y a quelques semaines, la prochaine version du SDK Flex (Flex 4.5) sera nommée Hero. Celle-ci comportera notamment des composants pour plate-formes mobiles bien pratiques. Pour plus d'informations, lire ce billet:

Hero – Le prochain Flex SDK (4.5) avec composants pour mobiles

Et aujourd'hui, la Product Manager de Flex, Deepa Subramaniam a annoncé sur son blog, le premier build public de ce SDK:

Exciting Developments with Hero

Ce build (4.5.0.17077) peut être téléchargé sur le site Open Source @ Adobe:

Télécharger le dernier build de Hero Flex 4.5

Ce build est le premier, il est donc incomplet et sûrement buggé. Pas de composants mobiles dans cette version (pour l'instant!), voici les fonctionnalités implémentées:

Je suis allé jeter un coup d'oeil sur les documentations (encore incomplètes elles aussi) et les composants Image et DataGrid sont vraiment cool!

Notamment la possibilité de donner une SkinPart à une image pour l'affichage du preloading de l'image. Plus besoin de faire une nouvelle classe qui va hériter de Image pour cela. Notez aussi que ce composant Image intègre directement une mise en cache des éléments chargés. Ici aussi, on aura plus besoin de SuperImage et autres.

Le composant Spark DataGrid est lui, le remplaçant de la DataGrid mais aussi, à terme, de l'AdvancedDataGrid. Lisez les specifications, les modifications apportées ont du sens :) .

Pour l'instant, ils ont trouvé le set de couleurs le plus moche pour les couleurs de rollover / selection de base :P :

hero-1

Remplis sous: Non classé 1 commentaire
19mar/102

Flex UIComponent – Déclencher l'évènement change lors de la modification du selectedItem en AS3 (ComboBox, List et DataGrid)

Sur les composants Flex de type List (ComboBox, List et DataGrid par exemple), on dispose d'un évènement ListEvent.CHANGE ("change") qui est dispatché quand l'utilisateur fait une sélection dans la liste. Il est légèrement différent de l'évènement "itemClick" qui n'est déclenché qu'au click sur un élément de la liste.

De manière générale, il vaut mieux utiliser "change" que "itemClick" car change va dispatcher un évènement lorsque l'utilisateur fera une sélection au clavier (avec les touches directionnelles).

Le problème

Lorsque l'utilisateur fait une sélection, on a bien un évènement CHANGE qui est dispatché. Cependant, si on fixe le "selectedItem" en ActionScript (code), vous pourrez voir que l'évènement ne sera pas dispatché et pourtant la sélection sera bien faite. L'affichage sera aussi mis à jour mais aucun évènement.

Dans votre code métier, vous voulez sûrement déclencher une action quand un élément est sélectionné, que ce soit par action utilisateur ou par code. L'évènement CHANGE est donc critique pour que votre code reste homogène.

La solution

Puisque le composant Flex ne le fait pas, vous pouvez créer votre propre ComboBox (par héritage) qui va rajouter ce comportement ou tout simplement dispatcher vous-même l'évènement CHANGE pour que votre programme se joue correctement. Voici un extrait de code qui réalise cette action:

...
secondComboBox.selectedItem = item;
secondComboBox.dispatchEvent(new ListEvent(ListEvent.CHANGE));
...

Exemple complet en ligne

Ci-dessous, la démonstration des deux comportements (avec et sans dispatch d'évènement):

21fév/105

Flex Tips – Adapter automatiquement la taille d'une List / DataGrid / ComboBox suivant la donnée

Voilà un petit "tip" que j'utilise très fréquemment pour créer des interfaces plus agréables à utiliser. Ce n'est pas grand chose mais c'est toujours un petit plus. Ce petit truc sert simplement à adapter la taille d'une composant de type "liste" (List / DataGrid / ComboBox) suivant le nombre de données qu'il doit afficher.

En effet, par défaut, ces composants affichent un certain nombre d'éléments de votre dataProvider:

  • 5 pour la ComboBox (le DropDown)
  • 6 pour la DataGrid
  • 7 pour la List

Prenons maintenant l'exemple dans lequel vous avez un dataProvider à 6 éléments pour votre ComboBox. Quand vous allez l'ouvrir, une scrollbar (barre de défilement) va apparaitre pour vous permettre d'accéder au 6ème élément. Pour accéder au 6eme (ou 7e, ...) élément, on doit donc effectuer un click de plus alors que ce ne serait pas vraiment nécessaire, on pourrait afficher un DropDown affichant les 6 éléments par exemple.

Pour définir le nombre d'éléments à afficher dans un composant Flex de type List, il existe une propriété nommée "rowCount". Il suffirait donc de mettre votre rowCount à 6 et le tour est joué. Mais on va être plus malin car on ne connait pas forcement le nombre d'élément à afficher à l'avance (peut-être même qu'il peut varier).

On va ici utiliser le Data Binding pour automatiser la tâche et ne pas se soucier du pourquoi et du comment. On va simplement faire un Binding (liaison dynamique) entre la propriété "rowCount" de notre composant de type "liste" et la propriété "length" de notre dataProvider (en admettant que ce soit un Collection comme une ArrayCollection).

Voici un petit exemple:

<mx:ComboBox dataProvider="{_listOperatorsDP}" rowCount="{_listOperatorsDP.length}"/>

Et magie du Binding, notre affichage sera exactement à la taille souhaitée, pas de scrollbar. Alors vous avez sûrement déjà pensé à un cas qui pose problème, c'est le cas où l'on a beaucoup d'élément. Dans ce cas, notre Binding fera que notre liste sera immense et en plus, vous n'aurez potentiellement pas de scrollbar.

La solution est donc de simuler un "rowCountMax" (qui n'existe pas) à l'aide d'une mini-expression de test (test ternaire en ligne):

<mx:ComboBox dataProvider="{_listOperatorsDP}" rowCount="{_listOperatorsDP.length > 15 ? 15 : _listOperatorsDP.length}"/>

Ici, on va s'arrêter à 15 éléments affichés au maximum. A vous d'appliquer ce "tip" dans vos applications pour les rendre plus agréables à utiliser.

Un petit exemple exposant la différence:

Flex Source Code Download: Télécharger le code source complet de l'application

This movie requires Flash Player 11

4nov/0915

Composant Flex – Interface de Pagination générique (exemple)

Il y a quelques semaines, je présentais sur Adobe Flex Tutorial un composant Flex nommé Paginator qui était une interface de pagination générique pour vos applications. Pour rappel, la pagination sert à présenter la donnée par bouts (pages) afin de ne pas noyer l'utilisateur. Dans un commentaire, CapoeiraDance demandait à voir un exemple d'application de ce composant. Voici donc un exemple que j'ai concocté moi-même.

Dans cet exemple, on a une donnée sur les états américains avec quelques valeurs. J'ai choisi de n'afficher que 8 éléments pas page pour montrer le fonctionnement de l'interface de pagination. La vraie pagination (au niveau de la data) se fait par une "filterFunction" sur le dataProvider (ArrayCollection). Ainsi, on va regarder l'index de l'item dans la donnée pour savoir s'il est dans la page courante. Le code n'est sûrement pas optimal mais cela donne une idée.

Attention, pour indiquer le nombre total d'éléments au paginator, on utilise bien la propriété "length" de la "source" de l'ArrayCollection et pas la "length" de l'ArrayCollection. En effet, si on utilise directement statesData.length, les résultats seront erronés car la fonction de filtre va modifier cette longueur.

J'aurai pu être chauvin et utiliser la DataFilterLib pour créer cette pagination mais gardons les choses simples pour l'instant :) .

Un peu de code pour commencer

 [Bindable]
  private var statesData:ArrayCollection = new ArrayCollection([...]);

  ...

  // variables utilisées par la fonction de filtre
  private var _startIdx:int = 0;
  private var _endIdx:int = 1000;

  private function init():void{
	// on donne une fonction de filtre à la donnée pour n'afficher que les résultats courants
	statesData.filterFunction = paginateFilterFunction;
	statesData.refresh();
  }

  private function pageChangeHandler(e:PaginateEvent):void{
	// affichage du nombre de résultats courant
	var page:int = e.index;

	var startIndex:int = (page * e.itemsPerPage) + 1;
	var endIndex:int = Math.min((startIndex + e.itemsPerPage -1), e.itemsTotal);
	_startIdx = startIndex - 1;
	_endIdx = endIndex;

	txt.text = "Results: " + String(startIndex) + " - " + String(endIndex) + " of " + e.itemsTotal;
	// filtrage de la donnée par page
	statesData.refresh();
  }

  private function paginateFilterFunction(item:Object):Boolean{
	var itemIdx:int = statesData.getItemIndex(item);
	return (itemIdx >= _startIdx && itemIdx < _endIdx) || itemIdx == statesData.source.length;
  }

  ...

  <local:PageSelector id="paginator"
					  itemsPerPage="{8}"
					  rangeCount="6"
					  itemsTotal="{statesData.source.length}"
					  selectedIndex="0"
					  pageChange="pageChangeHandler(event)" />

L'application en ligne

Flex Source Code Download: Télécharger le code source complet de l'application

This movie requires Flash Player 11

27sept/0918

DataFilterLib – Filtrer plusieurs vues en utilisant le DataBinding

Voici un nouvel exemple de la DataFilterLib qui montre simplement comment on peut mettre à jour plusieurs vues avec un seul filtre. Dans cet exemple, j'ai 4 composants qui ont tous comme dataProvider, la même ArrayCollection. J'ai ainsi une DataGrid, une TileList, une List et un Chart qui affichent ma donnée (donnée d'exemples avec des appareils photo).

Pour effectuer mon filtrage, j'utilise un filtre de type INTERVAL, que vous pouvez configurer à votre guise. Cet article explique le fonctionnement des DataFilterInterval en détail. Grâce au mécanisme de Data Binding entre mes vues et mon model, toutes les vues vont se mettre à jour pendant la modification du filtrage.

Démonstration en ligne (onglet "Filter multiple views")

This movie requires Flash Player 11