Flex/ Flex 3/ Flex 3 para Flex 4

Flex 3 para Flex 4: Scrollers, Alguém tem que usar o scroll

Arrrghh!!! Eu já vi gente xingando o Flex 4 em e-mails, dizendo que não consegue colocar scrolls nos containers, no application. Eu sei, eu entendo suas frustrações, tudo que é novo e difícil de fazer é irritante.
Tenha em mente o seguinte, no Flex 3, tudo que é container tem automaticamente um scroll herdado diretamente na classe, essa técnica é absurdamente fantástica, você não tem a preocupação em ajustar a tela, ela simplesmente acompanha o fluxo e cria um scroll para você, seja ele vertical ou horizontal.
Também no Flex 3 você facilmente habilitava ou desabilitava o scroll dos containers, seja ele qual for.

Por exemplo, veja esse código abaixo onde eu desabilito todas as barras de scroll.

1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	verticalScrollPolicy="off" horizontalScrollPolicy="off">
 
</mx:Application>

Ai, se você decide que apenas a barra vertical (scroll) seja exibida você faz assim.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="loop()" layout="vertical"  horizontalScrollPolicy="off">
 
<mx:Script>
		<![CDATA[
			import mx.controls.Label;
			import mx.containers.Canvas;
 
				/**
				 * Função apenas para gerar conteúdo para Área de Scroll
				 * */
				private function loop():void
				{
					var i:uint=0;
					for (i;i<99;i+=1){
						var obj:Canvas = new Canvas();
						var lbl:Label = new Label();
						lbl.setStyle('fontSize',20);
						lbl.text = "Panel Color item " + i;
						obj.width = this.width;
						obj.height = 50;
						obj.setStyle('backgroundColor',Math.random()*0xffffff);
						obj.addChild(lbl);
						this.addChild(obj);
					}
				}
 
 
		]]>
</mx:Script>
</mx:Application>

Resultado do código acima.
flex3scroll

Facilmente a famosa barrinha de rolagem vai aparecer apenas na vertical, e você vai conseguir rolar sobre o conteúdo.
Por padrão o scrollPolicy sempre é auto, ou seja, o que vier, agente aguenta e cria uma barrinha de rolagem para te ajudar.

Como é no Flex 4?

No Flex 4 é bem diferente do que você faz no Flex 3. Ao invés de você ter uma barra de rolagem aninhada ao código do container, você simplesmente esquece isso. A arquitetura atual do Flex 4 é baseada em composição.

Composição: Imagine vários blocos de lego, cada um deles é um componente que gera um brinquedo, boneco, castelo, carro que nesse caso são equivalentes a containers, então você compõe cada bloco do lego que é um diferente do outro, em um só componente principal. É assim que tudo funciona. Ou um outro exemplo bem louco é “assista o filme transformers 2”, a hora em que o avião doa peças para Optimus Prime e ele tem mais poderes. A grande sacada de composição é que tudo é plugável e desplugável.

Já que, composição agora é fichinha para você; Voltamos ao assunto. Então tudo no Flex 4 é feito disso, logicamente qualquer container é composto. Por um Group e Skin.
Existem 2 formas de você acrescentar um Scroller à qualquer container, que são:

Por Skin:

O Application possui uma Skin que define essa aparência dele, que está localizado no pacote spark.skins.spark.ApplicationSkin, basta copiar o conteúdo desse skin e criar um novo através do menu do Flash Builder File > New > MXML Skin. Detalhe é que o atual Flash Builder não consegue localizar o ApplicationSkin, então você pode criar qualquer componente Skin, depois remover o conteúdo e colar o conteúdo que você copiou do ApplicationSkin.

ApplicationSkin padrão é assim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?xml version="1.0" encoding="utf-8"?>
 
<!--
 
ADOBE SYSTEMS INCORPORATED
Copyright 2008 Adobe Systems Incorporated
All Rights Reserved.
 
NOTICE: Adobe permits you to use, modify, and distribute this file
in accordance with the terms of the license agreement accompanying it.
 
-->
 
<!--- The default skin class for the Spark Application component.
 
@see spark.components.Application
 
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
		xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled="0.5" alpha.disabledWithControlBar="0.5">
 
	<fx:Metadata>
		<![CDATA[
		/**
		* A strongly typed property that references the component to which this skin is applied.
		*/
		[HostComponent("spark.components.Application")]
		]]>
	</fx:Metadata>
 
	<fx:Script fb:purpose="styling">
		<![CDATA[
			/**
			 *  @private
			 */
			override protected function updateDisplayList(unscaledWidth:Number,
														  unscaledHeight:Number) : void
			{
				bgRectFill.color = getStyle('backgroundColor');
				super.updateDisplayList(unscaledWidth, unscaledHeight);
			}
		]]>
	</fx:Script>
 
	<s:states>
		<s:State name="normal" />
		<s:State name="disabled" />
		<s:State name="normalWithControlBar" />
		<s:State name="disabledWithControlBar" />
	</s:states>
 
	<!-- fill -->
	<!---
	A rectangle with a solid color fill that forms the background of the application.
	The color of the fill is set to the Application's backgroundColor property.
	-->
	<s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0"  >
		<s:fill>
			<!--- @private -->
			<s:SolidColor id="bgRectFill" color="#FFFFFF"/>
		</s:fill>
	</s:Rect>
 
	<s:Group left="0" right="0" top="0" bottom="0">
		<s:layout>
			<s:VerticalLayout gap="0" horizontalAlign="justify" />
		</s:layout>
 
		<!---
		@private
		Application Control Bar
		-->
		<s:Group id="topGroup" minWidth="0" minHeight="0"
				 includeIn="normalWithControlBar, disabledWithControlBar" >
 
			<!-- layer 0: control bar highlight -->
			<s:Rect left="0" right="0" top="0" bottom="1" >
				<s:stroke>
					<s:LinearGradientStroke rotation="90" weight="1">
						<s:GradientEntry color="0xFFFFFF" />
						<s:GradientEntry color="0xD8D8D8" />
					</s:LinearGradientStroke>
				</s:stroke>
			</s:Rect>
 
			<!-- layer 1: control bar fill -->
			<s:Rect left="1" right="1" top="1" bottom="2" >
				<s:fill>
					<s:LinearGradient rotation="90">
						<s:GradientEntry color="0xEDEDED" />
						<s:GradientEntry color="0xCDCDCD" />
					</s:LinearGradient>
				</s:fill>
			</s:Rect>
 
			<!-- layer 2: control bar divider line -->
			<s:Rect left="0" right="0" bottom="0" height="1" alpha="0.55">
				<s:fill>
					<s:SolidColor color="0x000000" />
				</s:fill>
			</s:Rect>
 
			<!-- layer 3: control bar -->
			<!--- @copy spark.components.Application#controlBarGroup -->
			<s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
				<s:layout>
					<s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7" paddingBottom="7" gap="10" />
				</s:layout>
			</s:Group>
		</s:Group>
 
		<!--- @copy spark.components.SkinnableContainer#contentGroup -->
		<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />
	</s:Group>
</s:Skin>

Veja que logo aqui, no finalzinho existe, um componente Group chamado contentGroup. É ai que o conteúdo do Application fica guardado, então claro vamos aplicar um Scroll nesse camarada, o que resulta no seguinte conteúdo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?xml version="1.0" encoding="utf-8"?>
 
<!--
 
ADOBE SYSTEMS INCORPORATED
Copyright 2008 Adobe Systems Incorporated
All Rights Reserved.
 
NOTICE: Adobe permits you to use, modify, and distribute this file
in accordance with the terms of the license agreement accompanying it.
 
-->
 
<!--- The default skin class for the Spark Application component.
 
@see spark.components.Application
 
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
		xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled="0.5" alpha.disabledWithControlBar="0.5">
 
	<fx:Metadata>
		<![CDATA[
		/**
		* A strongly typed property that references the component to which this skin is applied.
		*/
		[HostComponent("spark.components.Application")]
		]]>
	</fx:Metadata>
 
	<fx:Script fb:purpose="styling">
		<![CDATA[
			/**
			 *  @private
			 */
			override protected function updateDisplayList(unscaledWidth:Number,
														  unscaledHeight:Number) : void
			{
				bgRectFill.color = getStyle('backgroundColor');
				super.updateDisplayList(unscaledWidth, unscaledHeight);
			}
		]]>
	</fx:Script>
 
	<s:states>
		<s:State name="normal" />
		<s:State name="disabled" />
		<s:State name="normalWithControlBar" />
		<s:State name="disabledWithControlBar" />
	</s:states>
 
	<!-- fill -->
	<!---
	A rectangle with a solid color fill that forms the background of the application.
	The color of the fill is set to the Application's backgroundColor property.
	-->
	<s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0"  >
		<s:fill>
			<!--- @private -->
			<s:SolidColor id="bgRectFill" color="#FFFFFF"/>
		</s:fill>
	</s:Rect>
 
	<s:Group left="0" right="0" top="0" bottom="0">
		<s:layout>
			<s:VerticalLayout gap="0" horizontalAlign="justify" />
		</s:layout>
 
		<!---
		@private
		Application Control Bar
		-->
		<s:Group id="topGroup" minWidth="0" minHeight="0"
				 includeIn="normalWithControlBar, disabledWithControlBar" >
 
			<!-- layer 0: control bar highlight -->
			<s:Rect left="0" right="0" top="0" bottom="1" >
				<s:stroke>
					<s:LinearGradientStroke rotation="90" weight="1">
						<s:GradientEntry color="0xFFFFFF" />
						<s:GradientEntry color="0xD8D8D8" />
					</s:LinearGradientStroke>
				</s:stroke>
			</s:Rect>
 
			<!-- layer 1: control bar fill -->
			<s:Rect left="1" right="1" top="1" bottom="2" >
				<s:fill>
					<s:LinearGradient rotation="90">
						<s:GradientEntry color="0xEDEDED" />
						<s:GradientEntry color="0xCDCDCD" />
					</s:LinearGradient>
				</s:fill>
			</s:Rect>
 
			<!-- layer 2: control bar divider line -->
			<s:Rect left="0" right="0" bottom="0" height="1" alpha="0.55">
				<s:fill>
					<s:SolidColor color="0x000000" />
				</s:fill>
			</s:Rect>
 
			<!-- layer 3: control bar -->
			<!--- @copy spark.components.Application#controlBarGroup -->
			<s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
				<s:layout>
					<s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7" paddingBottom="7" gap="10" />
				</s:layout>
			</s:Group>
		</s:Group>
 
		<s:Scroller  id="scroller" width="100%" height="100%" hasFocusableChildren="true" horizontalScrollPolicy="off">
		<!--- @copy spark.components.SkinnableContainer#contentGroup -->
		<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" />
		</s:Scroller>
	</s:Group>
</s:Skin>

Seto a largura e altura em 100% e habilio o hasFocusableChildren para true,fazendo ele não perder o foco no objeto quando estiver navegando. E por último eu desabilito o scroll horizontalmente.

Uffa, feito o Skin, como eu aplico agora no Application ?

Lá no Application é super simples, através da propriedade de registro skinClass você apresenta o diretório e o arquivo de Skin que você criou. Desse jeito aqui.

1
2
<?xml version="1.0" encoding="utf-8"?>
<s:Application skinClass="com.riacycle.skins.ScrollerSkin" xmlns:fx="http://ns.adobe.com/mxml/2009"

Nesse meu caso eu criei um Path com o nome “com.riacycle.skins”, onde guardo meus Skins personalizados. O resto agora é lenda, basta repetir o código do Flex 3 no Flex 4, atento apenas as mudanças que você já sabe, ficando o código da Aplicação dessa maneira.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?xml version="1.0" encoding="utf-8"?>
<s:Application skinClass="com.riacycle.skins.ScrollerSkin" xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="loop()" >
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
 
 
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
		<fx:Script>
		<![CDATA[
			import com.riacycle.skins.ScrollerSkin;
 
			import mx.containers.Canvas;
 
			import spark.components.Label;
			import spark.skins.spark.ApplicationSkin;
				/**
				 * Função apenas para gerar conteúdo para Área de Scroll
				 * */
				private function loop():void
				{
					var i:uint=0;
					for (i;i<99;i+=1){
						var obj:Canvas = new Canvas();
						var lbl:Label = new Label();
						lbl.setStyle('fontSize',20);
						lbl.text = "Panel Color item " + i;
						obj.width = this.width;
						obj.height = 50;
						obj.setStyle('backgroundColor',Math.random()*0xffffff);
						obj.addElement(lbl);
						this.addElement(obj);
					}
				}
 
 
		]]>
	</fx:Script>
</s:Application>

Assim, você pode ter essa maneira simples, usando Skin, ou se você quer eliminar o uso do Skin, você simplesmente cria um Group e um Scroll que o abrace para gerar o mesmo comportamento.
Ficando o código assim:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="995" minHeight="600" creationComplete="loop()"  width="100%" height="100%">
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
 
	<fx:Script>
		<![CDATA[
			import com.riacycle.skins.ScrollerSkin;
 
			import mx.containers.Canvas;
 
			import spark.components.Label;
			import spark.skins.spark.ApplicationSkin;
			/**
			 * Função apenas para gerar conteúdo para Área de Scroll
			 * */
			private function loop():void
			{
				var i:uint=0;
				for (i;i<99;i+=1){
					var obj:Canvas = new Canvas();
					var lbl:Label = new Label();
					lbl.setStyle('fontSize',20);
					lbl.text = "Panel Color item " + i;
					obj.width = this.width;
					obj.height = 50;
					obj.setStyle('backgroundColor',Math.random()*0xffffff);
					obj.addElement(lbl);
					grupo.addElement(obj);
				}
			}
 
 
		]]>
	</fx:Script>
	<s:Scroller width="100%" height="100%">
		<s:Group id="grupo" height="100%">
			<s:layout>
				<s:VerticalLayout/>
			</s:layout>
		</s:Group>
	</s:Scroller>
</s:Application>

Super simples, tem mais coisa que gostaria de falar sobre Scrolls, mais eu deixo para um outro post mais específico.

Flex/ Flex 3 para Flex 4/ Flex 4

Flex 3 para Flex 4: ApplicationControlBar

Adeus AplicationControlBar, lembra que você fazia assim no Flex 3:


Flex 3 ApplicationControlBar

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:ApplicationControlBar>
		<!-- itens para ser adicionado -->
	</mx:ApplicationControlBar>
</mx:Application>

A grande sacada do ApplicationControlBar ficava por conta da propriedade dock=true, lembra? Ela ocupava toda a parte superior do Application. A grande desvantagem é que se você decidisse mudar o layout padrão dele que é alinhar sempre os items de forma orizontal da esquerda para direita, você teria que colocar outros containers, o que acaba ficando meio sem sentido, sempre um container dentro de outro container (preço caro a se pagar).

No Flex 4 eles criam um similar a ele, só que bem mais legal de trabalhar e passível de receber qualquer típo de layout. Veja como pode ser feito:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<s:layout>
		<s:BasicLayout/>
	</s:layout>
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
	<s:controlBarLayout>
		<s:VerticalLayout/>
	</s:controlBarLayout>
	<s:controlBarContent>
		<s:Label text="item 01"/>
		<s:Label text="item 02"/>
	</s:controlBarContent>
</s:Application>

Qual a vantagem do novo controlBarContent? Simples, aplicar qualquer tipo de layout, criar em qualquer componente uma barra de menu, o controlBarContent é aplicável em qualquer componente de Container.

Qual a desvantagem? Se você quiser mudar para parte inferior do seu Application, você vai ter que criar um novo Skin para seu Application. Coisa que no Flex 3 você apenas mudava a posição y sempre que fizesse um resize da App.

Flex/ Flex 3 para Flex 4/ Flex 3 SDK/ Flex 4

Flex 3 para Flex 4: Binding

Uma das grandes vantagens de usar o Flex é fazer uso do Databinding, coisa que ele faz muito bem para quem sabe usar. Databinding para quem não sabe é um língua solta. Tudo que acontece na variável que ele está de butuca, ele vai acabar contando para o patrão dele, ou seja o cara que está esperando a resposta da variável que ele está observando.

No Flex 3 você pode fazer binding da seguinte maneira:

1
2
3
4
 
<mx:Binding source="txtB.text" destination="txtA.text"/>
   <mx:TextInput x="154" y="68" id="txtA"/>
   <mx:TextInput x="154" y="122" id="txtB"/>

Ou você pode fazer assim:

1
2
3
4
5
6
7
8
9
10
11
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
 
			[Bindable]public var dados:ArrayCollection;
 
 
		]]>
	</mx:Script>
 
	<mx:List dataProvider="{dados}"/>

E diretamente em Classes, você pode bindar uma classe inteira assim:

1
2
3
4
5
6
7
8
9
10
11
12
package com.igorcosta.migracao.Binding
{
	[Bindable]
	public class BlogPost
	{
		public function BlogPost()
		{
		}
		public var valor:Number;
		public var debito:Number;
	}
}

Até ai tudo bem, lembrando que é sempre bom você ter cuidado ao uso do Binding, vai que você usa em excesso e depois seu aplicativo fica que nem uma carroça. Só que no Flex 3, Binding é possível apenas de um recurso para outro recurso, e não vice-versa nativamente. Você pode até ter alguns truques na manga como esse aqui:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
 
<mx:Binding source="txtA.text" destination="txtB.text" />
<mx:Binding source="txtB.text" destination="txtA.text"/>
	<mx:TextInput x="154" y="68" id="txtA"/>
	<mx:TextInput x="154" y="122" id="txtB"/>
	<mx:Label x="87" y="70" text="Campo A"/>
	<mx:Label x="87" y="124" text="Campo B"/>
 
 
	<mx:Script>
</mx:Application>

Se você tiver feito isso, é mais um problema para você se preocupar no futuro. Então é ai que vem no Flex 4 uma maneira super simples de fazer isso, chamado de Two-way-databinding, que é mais ou menos assim a sintaxe comparada com o último exemplo do Flex 3 acima:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
 
	<s:TextInput id="campoA"/>
	<s:TextInput id="campoB" text="@{campoA.text}"/>
</s:Application>

Através do @ eu consigo amarrar o dedo-duro do Binding tanto indo como vindo, em ambos os campos, independente da ordem que eu os altero, se alterar em 1, irá alterar em outro a propriedade text em ambos os campos.

Então da próxima vez que você for fazer isso do Flex 3 para o Flex 4, lembre-se do Two-way.

Flash Builder/ Flash Catalyst/ Flex/ Flex 3 para Flex 4/ Flex 3 SDK/ Flex 4/ Flex Builder 3/ Flex Builder 4

Flex 3 para Flex 4 : Estilos

Criar estilos no Flex 4 é quase igual a criar no Flex 3, atento apenas em pequenas mudanças devido essa fase de transição e suporte ao Halo. veja as mudanças.

Flex 3 para aplicar estilo na sua aplicação você fez:

1
2
3
4
5
6
7
< ?xml version="1.0" encoding="utf-8"?>
<mx : Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
	<mx : Style source="Estilo.css"/>
 
 
</mx>

No Flex 4 você faz:

1
2
3
4
5
6
7
8
9
< ?xml version="1.0" encoding="utf-8"?>
<s :Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<fx :Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx>
	<fx :Style source="Estilo.css"/>
</s>

Absolutamente não existe diferença entre o uso de um para o outro. Esse exemplo é apenas para uso de CSS externo ao código mxml. Uma vez que você não é tão inocente em escrever o CSS da sua aplicação dentro do próprio arquivo mxml do application.

Mudanças no namespace

Nem tudo são flores, você achou que isso ia passar direto, você pode usar e continuar usando seus componentes do Flex 3 restrito apenas alguns, contanto que respeitem as novas regras de ciclo de vida, você não terá problemas aparente.
O que mudou é que se você continuar usando seus componentes do Flex 3 com o Flex 4 para funcionar os estilos você terá que adicionar um namespace ao arquivo de CSS e também um seletor na frente de cada tag padrão do componente. Por exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* CSS file */
/* CSS file */
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
 
 
/*
 Para estilizar seu componente Button do Flex 3 você tem
que fazer isso
*/
mx|Button{
	  /* suas preferencias do CSS aqui */
}
 
/*
	Para usar o Button do pacote Spark você usa assim
*/
s|Button {
	/* suas preferencias do CSS aqui */
}

Veja que não só os css do Flex 3 ainda funcionam como também você poderá mesclar ambos os css, tanto do 4 quanto do 3.

Suporte da ferramenta Flash Builder para CSS:

Você estáva acostumado a ter o Flex Builder com sua facilidade absurda em criar CSS e customizar suas telas, deixando-as cute cute para seus usuários finais. Porém o time de desenvolvimento do Flash Builder (novo nome para o antigo Flex Builder), decidiu tirar o suporte ao CSS da ferramenta e obriga-lo a usar o Flash Catalyst e forcar você a ser um pouco mais ninja. Vai ver algum desenvolvedor com alma boa tenha portado o Flex 3 Style Explorer para o Flex 4 e assim facilitar novamente sua vida.

Flex/ Flex 3/ Flex 3 para Flex 4/ Flex 3 SDK/ Flex 4

Flex 3 para Flex 4: Namespaces

Houve uma grande polêmica quando estavam fazendo o novo Flex 4 à mais ou menos 1 ano atrás. Quando estavam falando dos novos namespaces e prefixos. Melhorou um pouco do que eles haviam criado devido a comunidade de desenvolvedores reclamarem por causa do problema, eles voltaram atrás e fizeram direito.

No Flex 3 você tem apenas 1 namespace original para criar aplicações Flex, que é:

1
xmlns:mx="http://www.adobe.com/2006/mxml"

Ele define tudo que seu aplicativo precisa para acessar componentes e classes originais do Framework em seu todo.
Só que agora é que vem um grande diferencial do que você estava acostumado a fazer no Flex 3 para o Flex 4. No Flex 4 tudo mudou, temos agora um namespace para cada parte do SDK, isso se da ao fato que temos agora uma nova forma de criar interfaces no Flex 4, através de Skins e o Flash Catalyst é um grande influenciador nesse sentido, além dos seus próprios namespaces o SDK do Flex 4 em sí, vem com vários namespaces pré-definidos, então para não prolongar mais e mais, focarei apenas no SDK.

No Flex 4 temos os seguintes namespaces:

1
2
3
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"

Tais namespaces representam cada parte do SDK por completo, os novos componentes do Flex 4 ficam no namespace com prefixo S, e os elementos core do SDK ficam no prefixo FX. Já os conhecidos componentes do Flex 3 continuaram no pacote de prefixo mx.

Cada namespace tem suas próprias propriedades, estilos, efeitos e vez ou outra você pode ficar empacado em achar que funciona no Flex 4, muito cuidado nesse aspecto por que mudou muita coisa mesmo para componentes do Flex 3 funcionarem perfeitamente no Flex 4.

Então uma aplicação típica no Flex 3 ficaria assim:

1
2
3
4
5
6
7
8
9
10
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
 
 
	</mx><mx :Script>
		< ![CDATA[
 
 
		]]>
	</mx>

No Flex 4 uma típica aplicação ficaria assim:

1
2
3
4
5
6
7
8
9
10
11
12
13
< ?xml version="1.0" encoding="utf-8"?>
<s :Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	<fx :Declarations>
	</fx>
 
	<fx :Script>
		< ![CDATA[
 
		]]>
	</fx>
</s>
Flex/ Flex 3 Charts/ Flex 3 Open-Source/ Flex 3 SDK/ Flex Componentes/ frameworks/ Open-source

DVM ou Pacote de gráficos agora é open-source

Parte da estratégia da Adobe em colocar o DVM em categoria open-source é justamente tentar envolver mais ainda a comunidade em ajuda-la a corrigir bugs e manter o SDK ativo para a próxima geração de aplicativos desenvolvidos com o SDK do Flex.

A parte boa dessa história é que antes você teria que desembolsar cerca de $249 para ter acesso ao código fonte do mesmo.

Ano passado ela já havia liberado o acesso ao código fonte do produto, porém não permitia o uso comercial do mesmo, já que você não tinha a licença. Essa sem dúvida em minha opinião foi o melhor movimento do tão requisitado e usado framework de gráficos da plataforma Flex.

Você pode baixar o SDK de gráficos + Olap Datagrid + Advanced Datagrid diretamente do site Open-source da Adobe. Visite

Comunidade/ Dicas/ Flex/ Flex 3/ Flex 4/ Flex Componentes/ Notícias

Tour de Flex aprenda por diversos exemplos

Particularmente nós acreditamos que o caminho mais curto de se aprender um conceito é vendo por exemplos.
E quando você se depara com uma documentação completamente técnica e nenhum exemplo vivo disso, chega a dar preguiça e acaba nem se quer terminando de ler o que havia começado.
Isso tem acontecido muito até a versão 3.0 do SDK do Flex, porém notamos uma ligeira mudança na maneira da equipe responsável pela documentação ver isso com outros olhos. Quem já anda lendo como nós a documentação do Flex 4, percebe que o conteúdo da linguagem de referência do Flex 4 possui uma quantidade extra de exemplos o que torna o aprendizado mais fácil.
Tornando o aprendizado mais fácil por meio de exemplos é o que o Tour de Flex promete, ele ajuda você a encurtar seu caminho no aprendizado e adotar mais rápido alguns exemplos e técnicas não apenas com o SDK do Flex, mas inclui exemplos de outros projetos open-sources e integração com terceiros.

Atualmente o Tour de Flex possui mais de 200 exemplos, os quais fica fácil aprender. Quem não lembra quando lançamos em 2006 os “40 projetos open-source”, explorando os recursos do SDK do Flex 2? Só no link direto foram mais de 2.400 downloads, o que nos faz pensar que realmente por exemplo o conceito aprende-se muito mais rápido.

É por isso que a partir de hoje, vamos colocar o badge para quem estiver visitando o blog, conhecer o projeto Tour de Flex e ir explorando os recursos do Flex 3.0 e já com alguns exemplos do Flex 4.0.

Flex/ Flex 3 how to/ Flex 3 SDK

#5 Flex How to: Como popular um menu e aplicar icones e eventos

Tem muita gente com essa dúvida, andamos pesquesando os arquevos da lista da Flex-Brasil, e percebemos que teve um número considerável sobre esse tópico.
Criar menus dinâmicos ou não em Flex é fácil, a definição de estrutura de seus itens é feita por um XML, sela ele interno ou externo.

O formato do arquevo xml que o MenuBar ou Menu lê, é pré-definido com alguns atributos que ambos os componentes já interpretam. São elas:

  • enabled – Habilita ou desabilita um item do menu.
  • groupName – Quando um item haje como radio Button, ou check Button de um grupo de itens.
  • icon – Coloca um item como imagem, herdando de um asset do tipo Class.
  • label – Nome que aparece no item do menu.
  • toggled – Seleciona ou escolhe o tipo do item marcando na seleção do item.
  • type – Especifica o tipo do item do menu com seus valores (check, radio e separator)

Exemplo do meumenu.xml :



		
                
                
                	
                
                

            
            		
            		
            
            
                
                
                
            
            

Em alguns tags do exemplo acima usei as propriedades definidas do xml que é automaticamente interpretada pelo menu. Lembrando que se meu XML tem formato E4X , precisa-se setar o labelField do Menubar, que para acessar um atributo no XML só basta ler com @ e o nome da propriedade.

O resultado do XML acima pode ser aplicado dentro do Flex, como mostra o exemplo abaixo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
</mx><mx :XML id="meumenu" xmlns="" format="e4x">
<root>
		<menuitem label="Arquevo">
                <menuitem label="Novo Painel"/>
                </menuitem><menuitem label="Abrir">
                	<menuitem label="Ultimos..."/>
                </menuitem>
                <menuitem label="Fechar" enabled="false"/>
 
            <menuitem label="Editar">
            		<menuitem label="Titulo"/>
            		<menuitem label="Tamanho"/>
            </menuitem>
            <menuitem label="Visualizar">
                <menuitem label="50%"
                    type="radio" groupName="grupo"/>
                <menuitem label="100%"
                    type="radio" groupName="grupo"
                    selected="true"/>
                <menuitem label="150%"
                    type="radio" groupName="grupo"/>
            </menuitem>
            </root>
</mx>
<mx :MenuBar dataProvider="{meumenu.menuitem}" labelField="@label" width="100%"/>

Para se usar com ícone, você deve setar a propriedade iconField no MenuBar, para que o próprio possa setar o valor da imagem. Lembrando que sempre com o tipo Class.
Auxiliando nesse ponto, você pode definir uma classe ou arquevo especificadamente para setar os icones de seu menu. Criei um arquevo simples que faz todo esse processo de Embed e converte para Class.

Como ficou o arquevo:

1
2
3
4
5
6
7
8
9
10
11
12
13
// ActionScript file
 
[Embed(source="./assets/dev.png")]
[Bindable]
public var iconeDev:Class;
 
[Embed(source="./assets/book.png")]
[Bindable]
public var iconeBook:Class;
 
[Embed(source="./assets/info.png")]
[Bindable]
public var iconeInfo:Class;

Depois que definir isso, só trato de verificar se o iconField, foi definido no MenuBar e também o atributo tem o nome específico setado pela variável criada no arquevo “includeIcones.as”.

Como fica o exemplo com ícones.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :Script>
	< ![CDATA[
		include "includeIcones.as";
 
 
	]]>
</mx>
<mx :XML id="meumenu" xmlns="" format="e4x">
<root>
		<menuitem label="Arquevo" icon="iconeDev">
                <menuitem label="Novo Painel"/>
                </menuitem><menuitem label="Abrir">
                	<menuitem label="Ultimos..."/>
                </menuitem>
                <menuitem label="Fechar" enabled="false"/>
 
            <menuitem label="Editar">
            		<menuitem label="Titulo" icon="iconeBook"/>
            		<menuitem label="Tamanho"/>
            </menuitem>
            <menuitem label="Visualizar" icon="iconeInfo">
                <menuitem label="50%"
                    type="radio" groupName="grupo"/>
                <menuitem label="100%"
                    type="radio" groupName="grupo"
                    selected="true"/>
                <menuitem label="150%"
                    type="radio" groupName="grupo"/>
            </menuitem>
            </root>
</mx>
<mx :MenuBar iconField="@icon" dataProvider="{meumenu.menuitem}" labelField="@label" width="100%"/>

Como fazer para selecionar Itens do Menu e atribuir Eventos a cada item?

Atribuir ao MenuBar o evento de click e saber qual ícone foi selecionado, fica a cargo da propriedade itemClick do MenuBar,Menu.

Veja exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :Script>
	< ![CDATA[
		import mx.controls.Alert;
        import mx.events.MenuEvent;
 
		include "includeIcones.as";
 
            private function handleItemClick(event:MenuEvent):void {
 
                Alert.show('Menu escolhido foi: '+ event.item.@label);
            }
 
 
	]]>
</mx>
<mx :XML id="meumenu" xmlns="" format="e4x">
<root>
		<menuitem label="Arquevo" icon="iconeDev">
                <menuitem label="Novo Painel"/>
                </menuitem><menuitem label="Abrir">
                	<menuitem label="Ultimos..."/>
                </menuitem>
                <menuitem label="Fechar" enabled="false"/>
 
            <menuitem label="Editar">
            		<menuitem label="Titulo" icon="iconeBook"/>
            		<menuitem label="Tamanho"/>
            </menuitem>
            <menuitem label="Visualizar" icon="iconeInfo">
                <menuitem label="50%"
                    type="radio" groupName="grupo"/>
                <menuitem label="100%"
                    type="radio" groupName="grupo"
                    selected="true"/>
                <menuitem label="150%"
                    type="radio" groupName="grupo"/>
            </menuitem>
            </root>
</mx>
<mx :MenuBar itemClick="handleItemClick(event)" iconField="@icon" dataProvider="{meumenu.menuitem}" labelField="@label" width="100%"/>
Notícias

#4 Flex How to: Como filtrar coleção de dados

Filtrar é uma boa pedida para quem tem uma coleção de dados na sua tela e não gostaria de ficar chamando novamente seus serviços remotos com novos selects baseados em parametros passados. O que na verdade é uma má prática.
Filtrar um ArrayCollection,XMLCollection,Array,XML é sem dúvida ótimo começo, e deixa o aplicativo mais leve e rápido de executar na máquena do usuário.

Então como fazer?
Vamos usar o FilterFunction, que é uma propriedade pública e herdade pelo ArrayCollection e XMLListCollection da classe ListCollectionView.

Imagine que temos os seguinte exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :ArrayCollection id="clientes" filterFunction="filtrarSexo">
		<mx :Object nome="Claudio Cavalcanti" sexo="m"/>
		<mx :Object nome="Miguel de Souza"  sexo="m" />
		<mx :Object nome="Daniela Moura" sexo="f" />
		<mx :Object nome="Fernando Bolk" sexo="m"/>
		<mx :Object nome="Carla Maduro" sexo="f" />
		<mx :Object nome="Maria Silva" sexo="f"/>
		<mx :Object nome="Marcelo Siqueira" sexo="m"/>
		<mx :Object nome="Florice Carneiro" sexo="f"/>
</mx>
 
	<mx :DataGrid dataProvider="{clientes}" x="40" y="74" width="510" height="268">
		</mx><mx :columns>
			<mx :DataGridColumn headerText="Nome" dataField="nome"/>
			<mx :DataGridColumn headerText="Sexo" dataField="sexo"/>
		</mx>
 
 
	<mx :HBox x="40" y="46">
		<mx :RadioButtonGroup id="filtrarGrupo"/>
		<mx :Label text="Filtrar por sexo:"/>
		<mx :RadioButton label="Feminino" groupName="filtrarGrupo"/>
		<mx :RadioButton label="Masculino" groupName="filtrarGrupo"/>
	</mx>

Lembrando, Toda vez que você aplicar filtros em sua coleção você deve chamar primeiro a coleção para depois filtrar(óbvio), porém se você está usando o LCDS ou paginando os resultados, você deve aplicar primeiro o filtro para depois chamar a coleção.

Agora só aplicar o filterFunction a coleção, eu posso aplicar quantos filtros forem necessários.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
		import mx.controls.Alert;
			public function filtrarF(item:Object):Object{
				switch(String(item.sexo)){
						case 'f':
								return true;
								break;
				}
				return false;
			}
			public function filtrarM(item:Object):Object{
				switch(String(item.sexo)){
						case 'm':
								return true;
								break;
				}
				return false;
			}
			public function filtrar():void{
					if(filtrarGrupo.selection.label == 'Feminino'){
							clientes.filterFunction = filtrarF;
							clientes.refresh();
					}else{
							clientes.filterFunction = filtrarM;
							clientes.refresh();
					}
			}

Quando se aplica o filtro você não está alterando em nada sua coleção de dados, eles apenas estão sendo filtrados, a coleção pega do lado do servidor continuará inalterada.

Código final do exemplo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
< ?xml version="1.0" encoding="utf-8"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
</mx><mx :Script>
	< ![CDATA[
		import mx.controls.Alert;
			public function filtrarF(item:Object):Object{
				switch(String(item.sexo)){
						case 'f':
								return true;
								break;
				}
				return false;
			}
			public function filtrarM(item:Object):Object{
				switch(String(item.sexo)){
						case 'm':
								return true;
								break;
				}
				return false;
			}
			public function filtrar():void{
					if(filtrarGrupo.selection.label == 'Feminino'){
							clientes.filterFunction = filtrarF;
							clientes.refresh();
					}else{
							clientes.filterFunction = filtrarM;
							clientes.refresh();
					}
			}
 
	]]>
</mx>
<mx :ArrayCollection id="clientes">
		<mx :Object nome="Claudio Cavalcanti" sexo="m"/>
		<mx :Object nome="Miguel de Souza"  sexo="m" />
		<mx :Object nome="Daniela Moura" sexo="f" />
		<mx :Object nome="Fernando Bolk" sexo="m"/>
		<mx :Object nome="Carla Maduro" sexo="f" />
		<mx :Object nome="Maria Silva" sexo="f"/>
		<mx :Object nome="Marcelo Siqueira" sexo="m"/>
		<mx :Object nome="Florice Carneiro" sexo="f"/>
</mx>
 
	<mx :DataGrid dataProvider="{clientes}" x="40" y="74" width="510" height="268">
		</mx><mx :columns>
			<mx :DataGridColumn headerText="Nome" dataField="nome"/>
			<mx :DataGridColumn headerText="Sexo" dataField="sexo"/>
		</mx>
 
 
	<mx :HBox x="40" y="46">
		<mx :RadioButtonGroup change="filtrar()" id="filtrarGrupo"/>
		<mx :Label text="Filtrar por sexo:"/>
		<mx :RadioButton label="Feminino" groupName="filtrarGrupo"/>
		<mx :RadioButton label="Masculino" groupName="filtrarGrupo"/>
	</mx>
Flex/ Flex 3 how to

#3 Flex How to : Como criar um player de Vídeo avançado

No SDK do Flex você não tem um player de vídeo avançado, você dispõe apenas de um VideoDisplay e o resto fica por conta de sua imaginação. O time do Flex SDK até pensou em incorporar um player de video já pronto, só arrastar e está pronto para uso. Porém não sei o que ocorreu que acabou que a idéia não foi para frente. Graças a comunidade Flexiana que está crescendo a cada dia que passa isso é possível ser feito sem ter que esperar pelo time do Flex SDK, você pode usar esse componente que tem todo o controle possível, play, pause, stop, controle de volume, barra progressiva, tudo que um bom e usual player de vídeo deva ter.

Passo-a-passo

Primeiro baixe aqui código fonte do VideoPlayer. Como ele não tem um arquevo binário para tal, basta copiar do arquevo zip que você baixou, o diretório ‘com’ para pasta src, que tem todas as classes necessárias para o player.

Feito isso, instancie-o assim:

< ?xml version="1.0" encoding="utf-8"?>

	
		< ![CDATA[

			[Bindable]
			private var filme:String = "http://seufilme.com/arquevo.flv";

			]]>
	
	

Fácil não?!