반응형

In this article I will create a custom Spark Panel component that will look something like this:

Spark Panel Component Skin

You can find the working example lower on this page.

There are five steps that you must take to create a new Flex 4 Skin (for any Spark component):

  1. Create a new MXML component that extends the SparkSkin class
  2. Define the states of the Skin. The default states for most of the components are normal and disabled
  3. Define the HostComponent between Metadata tags
  4. Specify all the graphical elements that are used by the custom Skin
  5. Define the skin parts for the skin

So the first thing that I did was to create a custom MXML component for the Spark Panel skin. I created this component in the skins folder and I named the custom skin PanelSkin.

The next step was to define the states of the skin. To see what states are available for any Spark component you should check out the Adobe ActionScript 3.0 Reference for the Adobe Flash Platform online documentation.

For the Spark Panel custom skin I used four states:

	<s:states>
		<s:State name="normal" />
		<s:State name="disabled" />
		<s:State name="normalWithControlBar" />
		<s:State name="disabledWithControlBar" />
	</s:states>

The normal and disabled states are the default states when the Panel does not have a Control Bar. The normalWithControlBar and disabledWithControlBar states are used when the Panel is defined with a Control Bar.

Next we need to specify the HostComponent between Metadata tags. The HostComponent will be the path to the Spark component that will be skinned. In this case: spark.components.Panel:

	<fx:Metadata>
		[HostComponent("spark.components.Panel")]
	</fx:Metadata>

Next I specified all the graphical elements of the skin:

	<s:BorderContainer color="0xAAAAAA" cornerRadius="7"
					   width="100%" height="100%">
		<s:Rect width="100%" height="45" 
				topLeftRadiusX="7" topLeftRadiusY="7" topRightRadiusX="7" topRightRadiusY="7"
				top="0">
			<s:fill>
				<s:LinearGradient rotation="90">
					<s:entries>
						<s:GradientEntry color="#bf0000" />
						<s:GradientEntry color="#ff0011" />
					</s:entries>
				</s:LinearGradient>
			</s:fill>
		</s:Rect>
 
		<s:Rect bottomLeftRadiusX="7" bottomRightRadiusX="7"
				y="45"
				width="100%" height="100%">
			<s:fill>
				<s:LinearGradient rotation="90">
					<s:entries>
						<s:GradientEntry color="#f8f8f8" />
						<s:GradientEntry color="#CCCCCC" />
					</s:entries>
				</s:LinearGradient>
			</s:fill>
		</s:Rect>
 
		<s:Rect width="100%" height="40" 
				excludeFrom="normal, disabled"
				bottomLeftRadiusX="7" bottomLeftRadiusY="7" bottomRightRadiusX="7" bottomRightRadiusY="7"
				bottom="0">
			<s:fill>
				<s:LinearGradient rotation="90">
					<s:entries>
						<s:GradientEntry color="#3f3f3f" />
						<s:GradientEntry color="#a5a5a5" />
					</s:entries>
				</s:LinearGradient>
			</s:fill>
		</s:Rect>
	</s:BorderContainer>

At a glance this looks like a lot of code, but it is actually pretty straight forward. I declared a BorderContainer and inside this another three Rect blocks for the Panel header, Panel body and Panel Control Bar.

Inside every Rect block I have LinearGradient with different colors for every Rect. In the last Rect I added this code excludeFrom="normal, disabled" which will exclude this Control Bar from the Skin when the panel is declared without the Control Bar.

The last step is to define the skin parts. The Spark Panel has three skin parts: contentGroup for the Panel body, controlBarGroup for the Panel Control Group and titleDisplay for the Panel Header:

	<s:Label id="titleDisplay" 
			 paddingLeft="15" paddingRight="15" paddingTop="15"
			 color="white"
			 fontSize="18"
			 fontWeight="bold"
			 fontStyle="italic"/>
 
	<s:Group id="contentGroup">
		<s:layout>
			<s:VerticalLayout paddingTop="55" paddingBottom="10" paddingLeft="15" paddingRight="15"
							  paddingBottom.disabledWithControlBar="55" paddingTop.disabledWithControlBar="55"
							  paddingBottom.normalWithControlBar="55" paddingTop.normalWithControlBar="55"/>
		</s:layout>
	</s:Group>
 
	<s:Group id="controlBarGroup" bottom="10">
		<s:layout>
			<s:HorizontalLayout paddingLeft="5" paddingRight="5"/>
		</s:layout>
	</s:Group>

Ok, that’s all as far as the Panel Custom Skin is concerned. Now I will focus on the applying the Custom Skin to a few Panel instance in the application. To apply a Custom Skin to a Spark component you will use skinClass property like this:

	<s:Panel id="myPanel1"
			 skinClass="skins.PanelSkin"
			 title="My first panel title">

Here is the resulting application:


View Source is enabled in the above example. To view the source files right click on the swf and choose “View Source” from the context menu.

Here is the complete source code for the main application:

<?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" 
			   viewSourceURL="srcview/index.html">
 
	<s:layout>
		<s:HorizontalLayout paddingTop="5" horizontalAlign="center" verticalAlign="middle"/>
	</s:layout>
 
	<s:Panel id="myPanel1"
			 skinClass="skins.PanelSkin"
			 title="My first panel title">
 
		<mx:Text text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. " 
				 width="200" />
 
		<s:controlBarContent>
			<s:Button label="First Button"/>
			<s:Button label="Second Button"/>
		</s:controlBarContent>
 
	</s:Panel>
 
	<s:Panel id="myPanel2"
			 skinClass="skins.PanelSkin"
			 title="My second panel title">
 
		<mx:Text text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. " 
				 width="200" />
 
	</s:Panel>
 
</s:Application>

And here is the complete source code for the Custom Skin Class:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin 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="0.5" 
			 blendMode="normal">
 
	<s:states>
		<s:State name="normal" />
		<s:State name="disabled" />
		<s:State name="normalWithControlBar" />
		<s:State name="disabledWithControlBar" />
	</s:states>
 
	<fx:Metadata>
		[HostComponent("spark.components.Panel")]
	</fx:Metadata> 
 
	<s:BorderContainer color="0xAAAAAA" cornerRadius="7"
					   width="100%" height="100%">
		<s:Rect width="100%" height="45" 
				topLeftRadiusX="7" topLeftRadiusY="7" topRightRadiusX="7" topRightRadiusY="7"
				top="0">
			<s:fill>
				<s:LinearGradient rotation="90">
					<s:entries>
						<s:GradientEntry color="#bf0000" />
						<s:GradientEntry color="#ff0011" />
					</s:entries>
				</s:LinearGradient>
			</s:fill>
		</s:Rect>
 
		<s:Rect bottomLeftRadiusX="7" bottomRightRadiusX="7"
				y="45"
				width="100%" height="100%">
			<s:fill>
				<s:LinearGradient rotation="90">
					<s:entries>
						<s:GradientEntry color="#f8f8f8" />
						<s:GradientEntry color="#CCCCCC" />
					</s:entries>
				</s:LinearGradient>
			</s:fill>
		</s:Rect>
 
		<s:Rect width="100%" height="40" 
				excludeFrom="normal, disabled"
				bottomLeftRadiusX="7" bottomLeftRadiusY="7" bottomRightRadiusX="7" bottomRightRadiusY="7"
				bottom="0">
			<s:fill>
				<s:LinearGradient rotation="90">
					<s:entries>
						<s:GradientEntry color="#3f3f3f" />
						<s:GradientEntry color="#a5a5a5" />
					</s:entries>
				</s:LinearGradient>
			</s:fill>
		</s:Rect>
	</s:BorderContainer>
 
	<s:Label id="titleDisplay" 
			 paddingLeft="15" paddingRight="15" paddingTop="15"
			 color="white"
			 fontSize="18"
			 fontWeight="bold"
			 fontStyle="italic"/>
 
	<s:Group id="contentGroup">
		<s:layout>
			<s:VerticalLayout paddingTop="55" paddingBottom="10" paddingLeft="15" paddingRight="15"
							  paddingBottom.disabledWithControlBar="55" paddingTop.disabledWithControlBar="55"
							  paddingBottom.normalWithControlBar="55" paddingTop.normalWithControlBar="55"/>
		</s:layout>
	</s:Group>
 
	<s:Group id="controlBarGroup" bottom="10">
		<s:layout>
			<s:HorizontalLayout paddingLeft="5" paddingRight="5"/>
		</s:layout>
	</s:Group>
 
</s:SparkSkin>
Posted by 1010