Creating SkinnableContainer skins for Flex mobile apps
Recently I was looking for an example on how to create a skin that would work with the SkinnableContainer component class in a Flex mobile application. It turned out I couldn’t find any examples available in the wild so I had to dig it out myself. So below is the approach I took, which can also work for others.
The first thing I found out is that there is a SkinnableContainerSkin class in the spark.skins.mobile package that extends MobileSkin class. This is a basic implementation that works out-of-the-box when you use SkinnableContainer in mobile projects. Its only behavior is setting a contentGroup property with a new instance of the Group class and drawing a background rectangle filled with color based on the backgroundColor style.
Now my goal, instead of drawing the background with AS3, was to use a custom FXG file with some rounded corners, simple stroke and gradient. The screenshot below demonstrates what I was looking for:
In order to achieve the example above I extended SkinnableContainerSkin as in the following snippet:
package { import spark.core.SpriteVisualElement; import spark.skins.mobile.SkinnableContainerSkin; public class MySkinnableContainerSkin extends SkinnableContainerSkin { protected var backgroundClass:Class; protected var background:SpriteVisualElement; public function MySkinnableContainerSkin() { super(); // Here could be a DPI dependent logic, for demo purposes it is not necessary backgroundClass = MySkinnableContainerBackground; } override protected function createChildren():void { // Adding container background background = new backgroundClass; addChild(background); // Creating content group instance super.createChildren(); } override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void { super.layoutContents(unscaledWidth, unscaledHeight); // Setting size of background container setElementSize(background, unscaledWidth, unscaledHeight); } override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void { // By default SkinnableContainerSkin draws Rect with backgroundColor but this is not // required in this case since background is constructed of MySkinnableContainerBackground fxg } } }
My FXG file content looked like this:
<?xml version='1.0' encoding='UTF-8'?> <Graphic xmlns:fc="http://ns.adobe.com/flashcatalyst/2009" xmlns:d="http://ns.adobe.com/fxg/2008/dt" xmlns="http://ns.adobe.com/fxg/2008" version="2.0" scaleGridLeft="10" scaleGridTop="10" scaleGridRight="90" scaleGridBottom="90"> <Rect radiusX="10" width="100" height="100"> <fill> <LinearGradient rotation="90"> <GradientEntry alpha="1.0" color="#CCCCCC" ratio="0"/> <GradientEntry alpha="1.0" color="#666666" ratio="1"/> </LinearGradient> </fill> <stroke> <SolidColorStroke color="#FF0000" weight="2"/> </stroke> </Rect> </Graphic>
And the way I can use it now in my Flex mobile projects is as follows:
<s:SkinnableContainer left="10" top="10" right="10" bottom="10" skinClass="MySkinnableContainerSkin"> <s:Label left="10" top="10" right="10" bottom="10"> <s:text>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam eget arcu et nibh vehicula pulvinar sit amet sit amet ligula. Duis a orci at nisi faucibus luctus. Quisque congue vulputate porttitor. Curabitur ac turpis nulla, a malesuada diam. Sed ullamcorper massa ac libero tincidunt vel ultrices odio cursus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce pharetra varius tortor id rutrum. Duis tempor, nisl sit amet scelerisque dignissim, lorem nisl vehicula leo, in auctor dolor turpis at nisl. Quisque bibendum faucibus turpis vitae pulvinar. Sed mollis risus eget turpis molestie laoreet. Aenean metus nulla, vestibulum at egestas quis, aliquet tempus lectus.</s:text> </s:Label> </s:SkinnableContainer>



HI Piotr,
great example. Though I have a question, why do you have to declare the MySkinnableContainer skin twice. As skinClass and explicitly adding it as child in the container constructor?
Mathias
18 Jul 11 at 9:45 am
@Mathias in the constructor is a FXP with a background not skin itself.
MySkinnableContainerSkin != MySkinnableContainerBackground
p.
Piotr Walczyszyn
18 Jul 11 at 10:13 am
Hi Piotr,
Awesome Post!
I’m new on flex mobile development,
So, Can I make a skinnable list ? or transform that in something like an accordion element ?
Ederson
19 Jul 11 at 3:23 pm