There are lots of great resources out there on how to skin your Flex applications. Quick recap: Flex supports two approaches to skinning: graphical and programmatic. Graphical skinning involves creating graphical assets in Flash, Photoshop, Fireworks, etc. and embedding them in your Flex application. Programmatic skinning involves creating an ActionScript class which defines the skin for a control. As you might guess, graphical skinning is easier, programmatic skinning more powerful.
One drawback to both approaches is that the skinned resources (SWF/PNG/GIF/etc. for graphical skins, the AS class file for programmatic skins) must be available at compile-time for the skins to be applied. Or do they? In this post I’ll describe a neat trick for pulling in graphical skins at run-time (using a live demo with source code).
To make this example as simple as possible, I’m going to create a Flex app that allows the Button control to be dynamically skinned. This app will pull down a skinning SWF at runtime, load the skins, and apply them to the Button control. Again, to keep it simple I’m going to use the skin template file provided in NJ’s skinning article, and apply the RadioButton skins to the Button control. (A tip of the cap to Roger Gonzalez and NJ for basically coming up with this solution.)
Step #1: Create a wrapper SWF for the skin assets
The skin assets are in the aforementioned skin template file. I want to create a wrapper SWF that my Flex app can load at runtime and from which it can extract the appropriate assets, in this case the four symbols for the RadioButton control. Here’s the source for wrapper SWF:
package
{
import flash.display.Sprite;
public class Wrapper extends Sprite
{
[Embed(source="flex_skins.swf",symbol="RadioButton_upIcon")]
public var rbUpSkin: Class;
[Embed(source="flex_skins.swf",symbol="RadioButton_downIcon")]
public var rbDownSkin: Class;
[Embed(source="flex_skins.swf",symbol="RadioButton_disabledIcon")]
public var rbDisabledSkin: Class;
[Embed(source="flex_skins.swf",symbol="RadioButton_overIcon")]
public var rbOverSkin: Class;
}
}
Step #2: Put the wrapper SWF on your web server
The Flex app needs to load the wrapper SWF from somewhere!
Step #3: In your Flex app, use a Loader to load the wrapper SWF
I created a utility class called ClassLoader to wrap up functionality related to loading the SWF and extracting the class. Here are the key lines:
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
…
request = new URLRequest(swfLib);
var context:LoaderContext = new LoaderContext();
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
loader.load(request, context);
Notice that the Loader loads the SWF into an ApplicationDomain that has the current domain as its parent. This is the key to ensuring that the app can access the loaded class and its assets.
Step #4: Get the class from the loaded SWF and instantiate it
Here we load the Class using an agreed-upon className (in this case, “Wrapper”):
阅读全文 »
Tags »
Flex/Flash|
Flex2|
RSL|
Skin