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.

2 thoughts on “Flex 3 para Flex 4: Scrollers, Alguém tem que usar o scroll

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios são marcados com *