Setting a background fill on an invalid Spark Image control in Flex Hero

In a previous example, “Setting the background color on an invalid Spark Image control in Flex Hero”, we saw how you could set the background color on an invalid Spark Image control in Flex Hero by setting the backgroundColor style on the invalid skin state.

The following example shows how you can create a custom bitmap fill on a Spark Image control in Flex Hero by creating a custom skin class and creating a BitmapFill object in the invalid skin state for the background skin part.

The following example(s) require Flash Player 10 and the beta Adobe Flex Hero SDK. To download the Adobe Flash Builder 4 trial, see www.adobe.com/products/flex/. To download the latest nightly build of the Flex Hero SDK, see opensource.adobe.com/wiki/display/flexsdk/Download+Flex+Hero.

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/10/25/setting-a-background-fill-on-an-invalid-spark-image-control-in-flex-hero/ -->
<s:Application name="Spark_Image_skinClass_invalid_BitmapFill_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx">
    <s:controlBarContent>
        <s:Form>
            <s:FormItem label="source:">
                <s:layout>
                    <s:HorizontalLayout />
                </s:layout>
                <s:Button label="image1.jpg"
                        click="img.source = 'http://helpexamples.com/flash/images/image1.jpg';"
                        chromeColor="haloGreen" />
                <s:Button label="logo"
                        click="img.source = 'http://helpexamples.com/flash/images/logo.png';"
                        chromeColor="haloGreen" />
                <s:Button label="(404)"
                        click="img.source = 'http://helpexamples.com/flash/images/404.gif';"
                        chromeColor="red" />
                <s:Button label="(null)"
                        click="img.source = null;" />
            </s:FormItem>
        </s:Form>
    </s:controlBarContent>
 
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx";
 
        s|Image {
            backgroundColor: white;
        }
    </fx:Style>
 
    <s:Image id="img"
             width="200" height="200"
             horizontalCenter="0" verticalCenter="0"
             skinClass="skins.CustomImageSkin"/>
 
</s:Application>

And the custom Spark Image skin class, skins/CustomImageSkin.mxml, is as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/10/25/setting-a-background-fill-on-an-invalid-spark-image-control-in-flex-hero/ -->
<s:Skin name="CustomImageSkin"
        xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
        alpha.disabled="0.5">
    <!-- states -->
    <s:states>
        <s:State name="uninitialized" />
        <s:State name="loading"/>
        <s:State name="ready" />
        <s:State name="invalid" />
        <s:State name="disabled" />
    </s:states>
 
    <!-- host component -->
    <fx:Metadata>
        [HostComponent("spark.components.Image")]
    </fx:Metadata>
 
    <fx:Script fb:purpose="styling">
        <![CDATA[
            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
                // Push backgroundColor and backgroundAlpha directly.
                // Handle undefined backgroundColor by hiding the background object.
                if (isNaN(getStyle("backgroundColor"))) {
                    background.visible = false;
                    background.includeInLayout = false;
                } else {
                    background.visible = true;
                    background.includeInLayout = true;
                    bgFill.color = getStyle("backgroundColor");
                    bgFill.alpha = getStyle("backgroundAlpha");
                }
 
                super.updateDisplayList(unscaledWidth, unscaledHeight);
            }
        ]]>
    </fx:Script>
 
    <!-- Defines the appearance of the image background. -->
    <s:Rect id="background" left="0" right="0" top="0" bottom="0">
        <s:fill>
            <s:SolidColor id="bgFill"/>
        </s:fill>
        <s:fill.invalid>
            <s:BitmapFill source="@Embed('skins/stripe.png')" fillMode="repeat" />
        </s:fill.invalid>
    </s:Rect>
 
    <!-- Primary image display part -->
    <s:BitmapImage id="imageDisplay"
            left="0" top="0" right="0" bottom="0"/>
 
    <!-- Progress indicator part -->
    <s:Range id="progressIndicator"
            skinClass="spark.skins.spark.ImageLoadingSkin"
            includeIn="loading"
            layoutDirection="ltr"
            verticalCenter="0" horizontalCenter="0" />
 
    <!-- Invalid image icon -->
    <s:BitmapImage source="@Embed('Assets.swf#__brokenImage')"
            includeIn="invalid"
            verticalCenter="0" horizontalCenter="0"/>
 
</s:Skin>

This entry is based on a beta version of the Flex Hero SDK and therefore is very likely to change as development of the Flex SDK continues. The API can (and will) change causing examples to possibly not compile in newer versions of the Flex Hero SDK.