Archive for November, 2009

Flex 4 Bidirectional Data Binding

Posted in Adobe Flex, Flex 4 with tags , , , on November 18, 2009 by devgirl

One cool feature that really simplifies things in Flex 4 is the new way to achieve bidirectional or two-way data binding. Bidirectional data binding basically allows you to use a property as both a source and destination for a value. You use the @ symbol outside of your curly braces that you would normally use for binding. So for instance in the following code snippet, the properties on ‘contact’ (bindable value object) are both displayed and stored as they are changed:

<mx:Form id="contactForm" defaultButton="{submitBtn}" width="100%" height="100%">
	<mx:FormItem label="Name:">
		<s:TextInput id="nameTxt" text="@{contact.name}"/>
	</mx:FormItem>
	<mx:FormItem label="Address:">
		<s:TextInput id="address" text="@{contact.address}"/>
	</mx:FormItem>
	<mx:FormItem label="City:">
		<s:TextInput id="city" text="@{contact.city}"/>
	</mx:FormItem>
	<mx:FormItem label="State:">
		<s:TextInput id="state" text="@{contact.state}"/>
	</mx:FormItem>
	<mx:FormItem label="Zip:">
		<s:TextInput id="zip" text="@{contact.zip}" maxChars="5"/>
	</mx:FormItem>
	<mx:FormItem>
		<s:Button id="submitBtn" label="Submit" click="submitBtn_clickHandler(event)"/>
	</mx:FormItem>
</mx:Form>

In Flex 3 we need to explicitly save those properties in the submit button click handler for instance to ensure the inputs were saved. There is also a way to do bidirectional binding in Flex 3 using either a combination of curly braces, <mx:binding> statements or using the mx.binding.utils.BindingUtils.bindProperty() method, but the shorthand notation introduced in Flex 4 really simplifies things and helps us pass our data between application layers automatically and effortlessly. You do need to make sure that your source and destination types are the same. And one more thing to note if it’s not already obvious is that using data binding in Flex does not come without a cost. When any type of data binding is done in Flex, code is generated to throw events and other processing occurs behind the scenes to make this happen, so if performance is a big concern, be wary of this. Specific details about this new feature can be found here.

I also recently added a more extensive sample of how this is done to Tour de Flex. You can find it under the Flex 4 | Coding Techniques section of the tree (sample 2), or here in the Tour de Flex web version.

Advertisements

Tabbed Navigation in Flex 4

Posted in Flex 4, Flex/AIR with tags , , , , , on November 16, 2009 by devgirl

If you didn’t know it already, the philosophy behind Flex 4 is ‘pay as you go’ for performance reasons. The goal was to reduce overhead and create lightweight components as a rule, so many things we were used to in Flex 3 are no longer included out of the box and it now requires some modification to the approach we take in building our apps. I recently created a Tour de Flex sample showing how you can do tabbed navigation with Flex 4 and wanted to share a simple example here too with a bit of explanation. One big benefit from my point of view is to be able to control the look and feel of my tabbed navigation quickly and easily with the new Flex 4 skinning model. For instance I could easily change the tab button borders, add icons to them etc with this approach.

We would implement the same tabbed navigation in Flex 4 by using the Spark TabBar control with a ViewStack. The best way to show this is by example:

<?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/halo" width="400" height="300">
	
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
	<s:TabBar id="tabs" left="8" y="2" dataProvider="{vs}"/>
	
	<mx:ViewStack id="vs" width="95%" height="85%" left="8" y="23">
		<s:NavigatorContent label="Tab 1"  width="100%" height="100%">
			<s:Border width="100%" height="100%" borderWeight="2" cornerRadius="3" dropShadowVisible="true">
				<s:Label left="3" top="5" text="This is my first tab..."/>
			</s:Border>
		</s:NavigatorContent>
		<s:NavigatorContent label="Tab 2"  width="100%" height="100%">
			<s:Border width="100%" height="100%" borderWeight="2" cornerRadius="3" dropShadowVisible="true">
				<s:Label left="3" top="5" text="This is my second tab..."/>
			</s:Border>
		</s:NavigatorContent>
		<s:NavigatorContent label="Tab 3"  width="100%" height="100%">
			<s:Border width="100%" height="100%" borderWeight="2" cornerRadius="3" dropShadowVisible="true">
				<s:Label left="3" top="5" text="This is my third tab..."/>
			</s:Border>
		</s:NavigatorContent>
	</mx:ViewStack>
</s:Application>

Here is a screenshot of the above code running:

Picture 11

This is just a very simple example of how you can achieve a similar look to the Flex 3 TabNavigator, but now if you want to change the look of the tabs you can just apply a new custom TabBarSkin via the skinClass property on the TabBar control:

<s:TabBar" id="tabs" left="8" y="2" dataprovider="{vs}" 2="skinClass="skins.MyTabBarSkin"/>

If you want to change the look of the tab bar buttons themselves then you would also need a custom TabBarButtonSkin that would be referred to from the dataGroup within MyTabBarSkin.mxml. I created a couple of more sophisticated examples showing this within Tour de Flex, and the custom skin classes are included. The second sample called ‘Custom Tabs’ shows how you can add an icon to the tabs as well. These samples can be found under the Flex 4 category (under Groups/Containers) or here in the Tour de Flex web version if you’d like to see more.

Beginner’s Guide to Skinning your Flex 4 Application or AIR Application

Posted in Adobe Flex, Flex 4, Flex/AIR with tags , , , , on November 9, 2009 by devgirl

While working on the Tour de Flex samples for Flex 4, I spent some time digging into the new Flex 4 Skinning Architecture and found that I could do some really cool stuff with it. Though I’m definitely NOT a designer, I was impressed by the level of control it offered me and wanted to share some basics/tips for skinning your Flex/AIR applications.

So you want to skin your app… where do you start?

1) Copy the source code for the default ApplicationSkin.mxml or WindowedApplicationSkin.mxml file from the Flex 4 SDK source into a new MXML component file within your project. The path should be something like: /<your-flex4-sdk-folder>/frameworks/projects/spark/src/spark/skins/spark/ (or on Windows it would be c:\..\<your-flex4-sdk-folder>\frameworks\projects\spark\src\spark\skins\spark\). You can also use the default skins specified in the Wireframe Flex 4 theme included in the SDK. They are sometimes simpler to work with (for more info on Flex 4 themes, see this link). The path to the wireframe skins will be something like: /<your-flex4-sdk-folder>/frameworks/projects/wireframe/src/spark/skins/wireframe/ (or on Windows it would be c:\..\<your-flex4-sdk-folder>\frameworks\projects\wireframe\src\spark\skins\wireframe\)

I figure what better way to make sure you have control over every detail than by starting with the Flex 4 SDK default skin class currently being used by the container or component. Many times you will not need that level of control and can omit parts of the code that are not changing, however I personally found it nice to see the options I had for modifying skin parts and the fact that they included comments in their skins to explain what each part is.

This is a quick and easy way to understand specifically which skin parts are defined as well. You can also check the Adobe Flex 4 Livedocs for that particular host component’s class documentation to see the required skin parts, skin states etc. Generally though I begin by just grabbing the skin source for the host component I want to skin and modifying or omitting different parts to see how it affected the component (so in the case of skinning an app I would look for either spark.components.ApplicationSkin.mxml or spark.components.WindowedApplication.mxml respectively).

Note: ‘host component’ simply refers to the Spark component/container I want to skin.

2) Change the parts you want to control. So for an Application you may want to modify the ApplicationControlBar look in addition to the background. This can all be done by modifying the source code for the ApplicationSkin.mxml class. Just rename it and modify it to your liking. These examples do not go into skinning the ApplicationControlBar, but you can apply the information from this post in doing so.

Quick Tip: if you just want to use a graphic for your application background, you could use a skin as simple as this:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
   xmlns:mx="library://ns.adobe.com/flex/halo"
   xmlns:s="library://ns.adobe.com/flex/spark">;

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

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

    <s:BitmapImage width="400" height="500" source="@Embed('assets/SampleBackground.png')"/>
    <s:Group id="contentGroup" left="0" right="0" top="0" bottom="0">
</s:SparkSkin>

Note: You must keep the ‘contentGroup’ part in your custom skin so the content of your application shows, otherwise you will only see your image. In the case of skinning an Application, the actual Application.mxml Livedocs will show you which skin parts are required. Scroll down until you see the section labeled Skin Parts in the class documentation. You can also view the inherited skin parts and skin states there.

If you want your image to actually fill in the entire space of the app, then you could use something like this:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
 xmlns:mx="library://ns.adobe.com/flex/halo"
 xmlns:s="library://ns.adobe.com/flex/spark">

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

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

 <s:Rect id="backgroundRect" left="0" right="0" top="0" bottom="0">
     <s:fill>
         <s:BitmapFill source="@Embed('assets/SampleBackground.png')"/>
     </s:fill>
 </s:Rect>

 <s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" />
</s:SparkSkin>

3) Apply the custom skin to your MXML application. You can do this in two ways, either inline MXML or CSS. For inline MXML, you simply set the skinClass property on the root Application tag to the fully-qualified name of your custom class. For instance:

    <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/halo
       skinClass="skins.CustomApplicationSkin">

In CSS it would be something like:

s|Application
{
    skinClass: ClassReference("com.devgirl.blogexample.skins.CustomApplicationSkin");
}

I generally use the skinClass property for application skins. The CSS way to do it is nice when you want to apply a certain skin to all instances of a component that you may have created a custom class for, such as Button for example.

Below are a couple of examples of skinning an application with a simple custom application skin (keeping in mind the fact that I am so NOT a designer ;)) but, they should help give an idea of what you are able to do. The screenshot is shown first followed by the source code for the custom skin and Flex app:

Picture 5

The custom background skin for the above screenshot looks like:

<?xml version="1.0" encoding="utf-8"?>
<!-- ../skins/BackgroundImageAppSkin.mxml>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
		xmlns:mx="library://ns.adobe.com/flex/halo" 
		xmlns:s="library://ns.adobe.com/flex/spark">
	
	<fx:Metadata>
		[HostComponent("spark.components.Application")]
	</fx:Metadata> 
	
	<s:states>
		<s:State name="normal" />
		<s:State name="disabled" />
	</s:states>
	
	<!-- This image fill also specifies padding around it -->
	<s:Rect id="backgroundRect" left="100" right="100" top="20" bottom="20">
		<s:fill>
			<s:BitmapFill source="@Embed('assets/wood-bg.png')"/>
		</s:fill>
	</s:Rect>	
	
	<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" />
</s:SparkSkin>

The Flex application code for this screenshot is the following:

<?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/halo" 
			   skinClass="skins.BackgroundImageAppSkin" 
			   backgroundColor="0x000000">
	
	<fx:Declarations/>
	
	<s:VGroup horizontalCenter="0" verticalCenter="0">
		<s:Label text="Wood Sales Int'l" fontSize="42" />
		<s:Border borderColor="0x000000" borderWeight="3" cornerRadius="7" horizontalCenter="0" verticalCenter="0">
			<s:VGroup>
				<mx:Form fontSize="16">
					<mx:FormItem label="Userid:">
						<s:TextInput id="userid"/>
					</mx:FormItem>
					<mx:FormItem label="Password:">
						<s:TextInput id="pw"/>
					</mx:FormItem>
					<mx:FormItem>
						<s:Button label="Login"/>
					</mx:FormItem>
				</mx:Form>
			</s:VGroup>
		</s:Border>
	</s:VGroup>
</s:Application>

Now I can change just one line in my sample code, the skinClass property to a different skin, and produce this:

Picture 7

And below is the custom gradient background skin for the above screenshot:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
		xmlns:mx="library://ns.adobe.com/flex/halo" 
		xmlns:s="library://ns.adobe.com/flex/spark">
	
	<fx:Metadata>
		[HostComponent("spark.components.Application")]
	</fx:Metadata> 
	
	<s:states>
		<s:State name="normal" />
		<s:State name="disabled" />
	</s:states>
	
	<!-- border -->
	<s:Rect left="10" right="10" top="10" bottom="10" radiusX="9" radiusY="9">
		<s:stroke>
			<mx:SolidColorStroke color="0xCCCCCC" alpha=".5" weight="4"/>
		</s:stroke>
	</s:Rect>

	<s:Rect id="backgroundRect" left="10" right="10" top="10" bottom="10" radiusX="9" radiusY="9">
		<s:fill>
			<s:LinearGradient rotation="90">
				<s:entries>
					<s:GradientEntry color="0x0000FF" ratio="0.00" alpha="0.8"/>
					<s:GradientEntry color="0x336699" ratio="1.0" alpha="0.5"/>
					<s:GradientEntry color="0xCCCCCC" ratio="0.5" alpha="0.8"/>
				</s:entries>
			</s:LinearGradient>	
		</s:fill>
	</s:Rect>
	
	<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" />
</s:SparkSkin>

Again, the sample Flex application MXML looks exactly the same except we are specifying my custom gradient background skin on the skinClass property:

<?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/halo" 
			   skinClass="skins.GradientBackgroundAppSkin">
	
	<fx:Declarations/>
	
	<s:VGroup horizontalCenter="0" verticalCenter="0">
		<s:Label text="Wood Sales Int'l" fontSize="42" />
		<s:Border borderColor="0x000000" borderWeight="3" cornerRadius="7" horizontalCenter="0" verticalCenter="0">
			<s:VGroup>
				<mx:Form fontSize="16">
					<mx:FormItem label="Userid:">
						<s:TextInput id="userid"/>
					</mx:FormItem>
					<mx:FormItem label="Password:">
						<s:TextInput id="pw"/>
					</mx:FormItem>
					<mx:FormItem>
						<s:Button label="Login"/>
					</mx:FormItem>
				</mx:Form>
			</s:VGroup>
		</s:Border>
	</s:VGroup>
</s:Application>

So you can see just how quickly you can make your application theme look entirely different with just a one line change and not modifying any behavioral logic. It’s very powerful and there are so many more things beyond this that you can do with the FXG drawing API’s.

A couple other tips for non-designer folks out there… You can use the Adobe CS4 products such as Photoshop, Illustrator and Fireworks etc to create your skins and then export them as FXG and use them within your skins. You do not have to understand all of the FXG classes and properties necessarily but can just visually draw what you want with those products and either do a ‘Save As’ .fxg extension type (such as in Photoshop), or use the Export to FXG command (from the Commands menu) in Fireworks. For instance, it may generate your FXG for a drawn border (using the Path FXG object) based on what you drew that you can use without having to figure all the specific points out. You can then extract the parts you want from the FXG and place them in your custom skin class. Many times you will also get an image as a result and will use that within your skin class as well, like I did in the wood sample above. The image is exported and referenced as part of the FXG from the CS4 tools. If you play around with it a bit and export the FXG to see what it created, you will quickly see what you can do.

Important to note: One FXG-related issue I ran into when exporting from Photoshop or Fireworks, is that there are times when what you produced will result in either a TextGraphic or BitmapGraphic in the FXG source and you must manually change them to RichText (for TextGraphic) and BitmapImage (for BitmapGraphic) or you will get compiler issues with the namespace. Detailed information about this can be found here.

Also, an obvious tip to most, but just in case it helps someone… When I create my new image, I always use the ‘Transparent’ background mode so that it fits in with whatever color scheme I might choose within the app. If you know exactly what color you are using already, you can set the background to that and it will matte it to that color. This is probably already known to many, but for those that might not know, it will save you time figuring out why there is a white border around your image in your app!

Also note, everything above can be applied to skinning your AIR applications as well. You simply start with the WindowedApplicationSkin.mxml default skin class from the Flex 4 SDK.

There’s so much to the skinning architecture to understand, that you should definitely check out the Flex 4 team blogs and Livedocs Help to complete your knowledge.