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

4nov/0812

Flex Navigator – Les composants ViewStack et TabNavigator

Ces composants de type view stack (ViewStack et TabNavigator) permettent de grouper un ensemble de conteneurs et d'en afficher qu'un seul à la fois. C'est utile si vous voulez faire une interface une page/un écran. La manière la plus simple d'utiliser un composant de ce type est d'utiliser le composant TabNavigator qui fonctionne un peu comme le composant Accordion. Il va ainsi vous permettre de créer une interface Flex avec onglets.

Voici un exemple d'utilisation de TabNavigator qui reprend le même contenu que l'exemple d'Accordion Flex:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" viewSourceURL="srcview/index.html">
	<mx:TabNavigator width="400" height="240">
		<mx:Form label="Nom" icon="@Embed(source='./application_form.png')">
			<mx:FormItem label="Prénom">
				<mx:TextInput id="first"/>
			</mx:FormItem>
			<mx:FormItem label="Middle Name">
				<mx:TextInput id="middle"/>
			</mx:FormItem>
			<mx:FormItem label="Last Name">
				<mx:TextInput id="last"/>
			</mx:FormItem>
		</mx:Form>
		<mx:Form label="Commentaires" width="100%" height="100%">
			<mx:FormItem label="Commentaires">
				<mx:TextArea width="200" height="100" id="comments"/>
			</mx:FormItem>
		</mx:Form>
	</mx:TabNavigator>
</mx:Application>

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

This movie requires Flash Player 11

Comme pour le composant Accordion, il faut fixer la propriété label du conteneur enfant pour que Flex puisse déterminer quel label afficher dans l'onglet.

Vous pouvez créer un view stack sans utiliser le TabNavigator. Il faut simplement créer un ViewStack avec des conteneurs enfant. Pour choisir quel enfant du ViewStack afficher, vous pouvez utiliser la propriété selectedIndex.

Ainsi, pour changer la vue d'un ViewStack en ActionScript, il suffit de faire (les composants sont 0-indexed):

viewStack.selectedIndex = 1;

Ensuite, il vous suffit d'assigner le ViewStack en tant que dataProvider d'une ButtonBar, LinkBar ou ToggleButtonBar:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" viewSourceURL="srcview/index.html">
	<mx:VBox>
		<mx:ToggleButtonBar dataProvider="{viewStack}"/>
		<mx:ViewStack id="viewStack" width="400" height="240">
			<mx:Form label="Nom" icon="@Embed(source='./application_form.png')">
				<mx:FormItem label="Prénom">
					<mx:TextInput id="first"/>
				</mx:FormItem>
				<mx:FormItem label="Middle Name">
					<mx:TextInput id="middle"/>
				</mx:FormItem>
				<mx:FormItem label="Last Name">
					<mx:TextInput id="last"/>
				</mx:FormItem>
			</mx:Form>
			<mx:Form label="Commentaires" width="100%" height="100%">
				<mx:FormItem label="Commentaires">
					<mx:TextArea width="200" height="100" id="comments"/>
				</mx:FormItem>
			</mx:Form>
		</mx:ViewStack>
	</mx:VBox>
</mx:Application>

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

This movie requires Flash Player 11

Articles similaires

Commentaires (12) Trackbacks (1)
  1. Bonjour,

    Tout d'abord, bravo pour votre site qui est très bien fait.
    J'ai cliqué sur un lien google, une façon à moi de vous aider (rire).

    Au sujet du TabNavigator : je cherche à le dériver pour y mettre dans les onglets, une petite croix.
    Exactement comme les onglets de Eclipse (je suppose que vous voyez ce que je veux dire (sourire))

    Si vous avez une idée, ou que vous trouver cette idée intéressante, n'hésitez pas en faire un tutoriel, je suis preneur !

    Vous pouvez me contacter par mail à olivier point pons at gmail point com !

    A bientôt,

  2. Salut,
    il y a un composant dans la Flexlib qui ressemble à ce que tu demandes, un tabnavigator avec des onglets que l'on peut fermer:
    http://code.google.com/p/flexlib/wiki/ComponentList
    Il s'appelle le SuperTabNavigator, utilisant la SuperTabBar.
    Exemple:
    http://flexlib.googlecode.com/svn/trunk/examples/SuperTabNavigator/SuperTabNavigator_Sample.swf
    Doc:
    http://flexlib.googlecode.com/svn/trunk/docs/flexlib/controls/SuperTabBar.html

    Fabien

  3. Bonjour,

    bon voila, je suis débutant en flex et les ViewStack me posent des soucis.
    Le truc c'est que dans mon programme je gère des cookies avec les shareObject pour mon authentification et la sauvegarde du style CSS.
    J'ai commencé à vouloir mettre en place un menu avec un ViewStack qui switch entre le
    module d'authentification et celui du changement de style de la page mais je ne vois pas
    du tout comment récupérer les données des ShareObject de mes modules situés dans la ViewStack.

    J'espère que vous m'avez compris car je ne suis pas souvent (même tout le temps) explicite :s

    merci d'avance pour ceux qui pourrons m'éclairer un peut sur ce dilemme.

  4. Euh... en fait je me suis aperçus de l'oublie du SelectedIndex dans mon initialisation...
    Du coup ça marche mieux ;)

    merci à moi même et merci pour ce site plein de ressources fortes intéressantes!

  5. Bonjour à tous,

    C'est encore moi et cette fois-ci j'aurai une question très simple. Je suis en passe de terminer le projet que je fais depuis 3 mois, et je peaufine certains details.
    Voici mon problème:
    J'ai ma classe main qui fait appelle à une autre classe effectDB. Pour l'appeller grâce à un evenement, voila comment je procède dans ma classe main:

    Actionscript:
    1. private function ClickEffect():void
    2. {
    3.   vs.selectedChild = view2;
    4. }

    MXML:
    1. <mx:ViewStack id="vs">
    2.   <mx:Canvas id="view2"/>
    3.     <MyComp:effectDB/>
    4.   </mx:Canvas>
    5. </mx:ViewStack>
    6. <mx:Button label="ok" click="ClickEffect()"/>

    Tout simplement, rien de bien difficile pour l'instant! Cependant ma classe effectDB contient une viewstack du nom de applicationScreens (que j'ai bien sur initialiser au canva que je voulais grâce à selectedIndex="0"). Je voudrai tout simplement à chaque fois que je clique sur mon bouton OK, que mon composant effectDB s'affiche avec le canva de sa viewstack que je veux, ici "0". Comment faire pour passer cela en argument de ma classe main à effectDB?

    Mon projet est un site, en cliquant sur OK, j'accède au comp effectDB, là je peux me ballader sur la viewstack applicationScreen, mais quand je veux revenir à l'accueil (la classe main) et que je repars sur effectDB, on m'affiche le dernier canva sur lequel j'étais, et non celui par défaut.

    J'espère avoir été assez clair. Merci de m'aider.

    Indiana

  6. Salut,
    alors plusieurs solutions, tu peux écouter l'évènement CHANGE sur le ViewStack et faire ton traitement suivant l'enfant sélectionné. Ou alors encore plus simple, quand tu arrives sur "view2" (en modifiant le selectedChild de ton ViewStack, view2 va lancer un évènement SHOW. Donc tu peux faire un truc du genre:

    MXML:
    1. <mx:Canvas id="view2" show="effectDB.applicationScreens.selectedIndex=0">
    2.  <MyComp:effectDB id="effectDB"/>
    3. </mx:Canvas>

    Fabien

  7. Merci beaucoup, ça marche!

    Je tiens tout de même à préciser que si l'on met comme id le nom de la classe, on obtient commme erreur "effectDB n'est pas une constante de compilation" ou quelque chose comme cela. Pour pâlier à ce probleme, il sufft tout simplement de mettre un id different, disons e, et dond la partie show devient:

    show="e.applicationScreens.selectedIndex=0"

    Un grand merci à Fabien, pour son site, ses réponses et sa réactivité!

    Indiana

  8. Bonjour,

    Les tutoriels sont super intéressants, mais il y a un aspect au sujet des viewStack que je n'ai pas vu.

    Voilà j'ai un viewStack contenant dix NavigatorContent. Dans neuf de ces NavigatorContent (contenant des formulaires de création de questions), j'ai un bouton "Ajouter un domaine" qui doit conduire vers le dixième NavigatorContent qu'on va appeler "Domaines". Jusque là, aucun gros problème. Sauf que dans "Domaine" j'ai un bouton "Valider" qui doit me ramener au NavigatorContent sur lequel je me situe. Ma question est comment faut-il faire pour qu'un clic sur ce bouton me ramène le NavigatorContent à partir duquel j'ai ouvert "Domaine"?

    Un exemple :
    J'ouvre le NavigatorContent "Question VRAI/FAUX", je clique sur le bouton "Ajouter un domaine". Cette action me conduit au NavigatorContent "Domaine". Dans la NavigatorContent "Domaine", je clique sur le bouton "Valider". Cette action doit me ramener sur le NavigatorContent "Question VRAI/FAUX" sur lequel je me situais.

    En plus clair, J'ai UN seul NavigatorContent "Domaine" qui doit pouvoir être ouvert par un clic sur le bouton "Ajouter un domaine" présent dans n'importe quel NavigatorContent de création de questions. Le clic sur le bouton "Valider" présent dans le NavigatorContent "Domaine" doit me ramener dans mon NavigatorContent par le biais duquel j'avais ouvert le NavigatorContent "Domaine".

    C'est assez difficile à expliquer donc je ne sais pas si j'ai bien développer ma demande.

    Merci de l'éclairage qui pourra m'être apporté.

    Nathalie

  9. Bonjour Nathalie,
    Je pense avoir compris votre problématique. Le composant ViewStack ne va pas se charger de telles logiques "métier", il va falloir l'implémenter vous même. Mais pas de panique, c'est très simple :) .
    En fait, ce qu'il vous faut, c'est une mémoire de l'index sélectionné précédemment pour pouvoir y revenir une fois que vous avez ajouté un Domaine. Lorsque vous cliquez sur "Ajouter un domaine", vous devez avoir une méthode commune (sinon en créer une) qui pour l'instant vous amène sur le NavigatorContent "Domaine". Cette méthode doit se situer dans un composant ou une classe. Il vous suffit de conserver en variable locale du composant, l'index (propriété selectedIndex)qui était le dernier sélectionné (votre mémoire). Lorsque vous validez votre domaine, vous allez récupérer cet index et diriger votre viewstack dessus (selectedIndex).

    C'est une méthode possible, il y en a d'autres mais cela dépend de comment vous avez organisé votre code.

    J'espère avoir compris votre demande :)

    Fabien

  10. Merci de cette réponse rapide.

    Je vais essayer de m'en sortir, si j'y arrive ...

    J'ai un second problème toujours avec les viewStacks et les NavigatorContent que je n'arrive pas à résoudre.

    Voilà, j'ai créé un MenuBar contenant une XMLList avec des item. Existe-t-il un moyen, une méthode, ou un truc du genre, afin que quand on clique sur un des items du MenuBar on puisse accéder au NavigatorContent correspondant qui est contenu dans un viewStack (ce viewStack contenant d'autres NavigatorContent en plus)?

    Un exemple :
    Menu "Questions"
    Item "Question VRAI/FAUX"
    Un clic sur ce item m'ouvrirait le NavigatorContent qui correspond à la Question VRAI/FAUX. (ce dernier contient un formulaire de création de ce type de question)

    Je ne maîtrise pas très bien le fonctionnement les XMLList ...

    Je vous remercie de votre aide.

    Nathalie

  11. Salut,
    Alors le XMLList ne va servir qu'à alimenter ton composant MenuBar (les labels). Pour répondre au click, il faut que tu écoutes un évènement sur le composant MenuBar. Avec l'évènement que tu vas récupérer, tu pourra récupérer l'élément qui a été cliqué, sa data. Dans ton cas, ce sera un noeud XML. Après, tu vas devoir écrire ta logique métier suivant le noeud cliqué (va sur un certain NavigatorContent dans ton cas). Il y a des exemples dans la documentation de MenuBar.

    Fabien

  12. Merci beaucoup pour la réponse.

    Bonne journée.

    Nathalie


Leave a comment

(required)