Thursday, January 08, 2009

I need help with Flex skinning using Flash CS4

I am learning how to create skins for my Flex apps in Flash CS4 and I'm finding there's multiple ways to do so.

In Flex 2 you would use ActionScript to embed a SWF that contains the skins for you app. You can do the same in Flex 3, but Adobe added the "Import Skin Artwork" feature which imports a SWC, not a SWF.

What I am trying to figure out is how to set the source of an <image> tag to the image symbol found in an "imported SWC."

To clarify my issue I'll elaborate further...

First I read...

They were all very helpful, but they showed a couple of ways to achieve the same thing, and most of the examples focused on skinning a button.

Here are the the basics that I learned:
1) Create your skin in Flash CS4.
2) Convert the skin to a symbol.
3) Publish the SWF or SWC...

  • For Flex 2:
    • Set the each symbols linkage to "Export for Actionscript."
    • Publish to a SWF that's embeded into the Flex 2 app.
  • For Flex 3:
    • Use "Convert Symbol to Flex component" (which is a available after installing the "Flex Component Kit for Flash CS3").
      Or, you could also set the each symbols linkage to "Export for Actionscript."
      I don't fully understand the difference yet.
    • Publish to a SWC and use the Flex "Import Skin Artwork" feature.

Where they differ is how to get the skin assets into flex probably due to differences between Flex 2 and 3.

In Flex 2 you would use code similar to this...


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Embed(source="assets/skins.swf", symbol="Canvas_backgroundImage")]
[Bindable]
public var test_background:Class;

[Embed(source="assets/skins.swf", symbol="Image_source")]
[Bindable]
public var test_image:Class;

[Embed(source="assets/skins.swf", symbol="Button_skin")]
[Bindable]
public var test_button:Class;
]]>
</mx:Script>

<mx:canvas backgroundImage="{test_background}" />
<mx:Image source="{test_image}" />
<mx:Button icon="{test_button}" />
</mx:Application>



You can use the same code in Flex 3, however Adobe introduced a new feature - "Import Skin Artwork." It's found under the File menu: File > Import > Skin Artwork...


When you "Import Skin Artwork" you have to:

1) Use a specific naming convention when creating your symbols in Flash.

2) Publish to a SWC (not a SWF).


Why publish to a SWC? The "Import Skin Artwork" functionality looks for a SWC which it will add to the library path of your Flex project. It also parses the symbol names found in the .SWC to create the CSS file used to apply the skins to your flex components.


First I created a Flash CS4 project named "skins," and I added three images and created the following symbol names:

  • Button_skin

  • Canvas_backgroundImage

  • Image_source


When I was done, I published my project creating the "skins.swc" file.


In Flex Builder 3 I imported "skins.swc" and Flex created the following "skins.css" File:


Button { skin: Embed(skinClass="Button_skin"); }
Canvas { backgroundImage: Embed(skinClass="Canvas_backgroundImage"); }
Image { source: Embed(skinClass="Image_source"); }





Note how the symbol names were parsed into the css:

  • Button_skin >> Button { skin: ...

    where "skin" is a style member of the Flex <mx:Button> component

  • Canvas_backgroundImage >> Canvas { backgroundImage: ...

    where "backgroundImage" is a style member of the Flex <mx:Canvas> component

  • Image_source >> Image { source: ...

    where "source" is a property (not a style member) of the Flex <mx:Image> component.

    This is where I believe my problem is, "source" is a property not a style member.


For more on this, read "Naming skin assets" on page 3 of the pdf "Importing Skins into Flex Builder"


Now for the MXML:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:com="com.*">
<mx:Style source="skins.css"/>
<!--- Canvas background is set from the CSS --->
<Canvas>
<!--- Button skin is set from the CSS --->
<mx:Button />
<!--- Image does not displayed --->
<mx:Image />
</Canvas>
</mx:Application>



I think because "source" is a property of the Flex <mx:Image> component and not a style member, it is being ignored.

However, I cannot code: [Embed(source="assets/skins.swc", symbol="Image_source")] because this throws compile error.


So, Is there a way to do this with an imported SWC?

Or do I have to create an imported SWC for skinning components and embed a SWF for image assets?


Thanks and I hope you may have learned something after reading all this as well!


Chris from flexdojo




2 comments:

Anonymous said...

Try using a ClassReference for the Image source that references the skin class name in your SWC instead: http://scalenine.com/blog/2008/07/08/skinclass-or-classreference-for-flash-skins/

source: ClassReference("Image_source");

FlexDojo said...

Juan,
You ROCK! That solved my problem.
Thanks,
Chris