Setting a bitmap fill on a Spark Button control in Flex 4

The following example shows how can apply a background bitmap fill on a Spark Button control in Flex 4 by creating a custom skin, using the BitmapFill class and setting the skinClass style.

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

For more information on getting started with Flex 4 and Flash Builder 4, see the official Adobe Flex Team blog.

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/04/29/setting-a-bitmap-fill-on-a-spark-button-control-in-flex-4/ -->
<s:Application name="Spark_Button_skinClass_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:Button id="btn"
            label="Spark Button w/ BitmapFill"
            skinClass="skins.CustomSparkButtonSkin"
            horizontalCenter="0" verticalCenter="0" />
 
</s:Application>

And the custom Spark Button control skin, skins/CustomSparkButtonSkin.mxml, is as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/04/29/setting-a-bitmap-fill-on-a-spark-button-control-in-flex-4/ -->
<s:SparkSkin name="CustomSparkButtonSkin"
             xmlns:fx="http://ns.adobe.com/mxml/2009"
             xmlns:s="library://ns.adobe.com/flex/spark"
             xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
             minWidth="21" minHeight="21"
             alpha.disabled="0.5">
    <!-- states -->
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>
 
    <!-- host component -->
    <fx:Metadata>
        [HostComponent("spark.components.Button")]
    </fx:Metadata>
 
    <fx:Script fb:purpose="styling">
        <![CDATA[
            /* Define the skin elements that should not be colorized.
            For button, the graphics are colorized but the label is not. */
            static private const exclusions:Array = ["labelDisplay"];
 
            override public function get colorizeExclusions():Array {
                return exclusions;
            }
 
            override protected function initializationComplete():void {
                useChromeColor = true;
                super.initializationComplete();
            }
 
            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void {
                var cr:Number = getStyle("cornerRadius");
 
                if (cornerRadius != cr) {
                    cornerRadius = cr;
                    shadow.radiusX = cornerRadius;
                    fill.radiusX = cornerRadius;
                    border.radiusX = cornerRadius;
                }
 
                if (highlightStroke) {
                    highlightStroke.radiusX = cornerRadius;
                }
                if (hldownstroke1) {
                    hldownstroke1.radiusX = cornerRadius;
                }
                if (hldownstroke2) {
                    hldownstroke2.radiusX = cornerRadius;
                }
 
                super.updateDisplayList(unscaledWidth, unscaledHeight);
            }
 
            private var cornerRadius:Number = 2;
        ]]>
    </fx:Script>
 
    <!-- layer 1: shadow -->
    <s:Rect id="shadow" left="-1" right="-1" top="-1" bottom="-1" radiusX="2">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0x000000" color.down="0xFFFFFF" alpha="0.01" alpha.down="0" />
                <s:GradientEntry color="0x000000" color.down="0xFFFFFF" alpha="0.07" alpha.down="0.5" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>
 
    <!-- layer 2: fill -->
    <s:Rect id="fill" left="1" right="1" top="1" bottom="1" radiusX="2">
        <s:fill>
            <s:BitmapFill source="@Embed('assets/pattern_143.gif')" fillMode="repeat" />
        </s:fill>
    </s:Rect>
 
    <!-- layer 5: highlight stroke (all states except down) -->
    <s:Rect id="highlightStroke" left="1" right="1" top="1" bottom="1" radiusX="2" excludeFrom="down">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0xFFFFFF" alpha.over="0.22" />
                <s:GradientEntry color="0xD8D8D8" alpha.over="0.22" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>
 
    <!-- layer 6: highlight stroke (down state only) -->
    <s:Rect id="hldownstroke1" left="1" right="1" top="1" bottom="1" radiusX="2" includeIn="down">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0x000000" alpha="0.25" ratio="0.0" />
                <s:GradientEntry color="0x000000" alpha="0.25" ratio="0.001" />
                <s:GradientEntry color="0x000000" alpha="0.07" ratio="0.0011" />
                <s:GradientEntry color="0x000000" alpha="0.07" ratio="0.965" />
                <s:GradientEntry color="0x000000" alpha="0.00" ratio="0.9651" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>
 
    <s:Rect id="hldownstroke2" left="2" right="2" top="2" bottom="2" radiusX="2" includeIn="down">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0x000000" alpha="0.09" ratio="0.0" />
                <s:GradientEntry color="0x000000" alpha="0.00" ratio="0.0001" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>
 
    <!-- layer 7: border - put on top of the fill so it doesn't disappear when scale is less than 1 -->
    <s:Rect id="border" left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="2">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0x000000" alpha="0.5625" alpha.down="0.6375" />
                <s:GradientEntry color="0x000000" alpha="0.75" alpha.down="0.85" />
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Rect>
 
    <!-- layer 8: text -->
    <s:Label id="labelDisplay"
             textAlign="center"
             verticalAlign="middle"
             maxDisplayedLines="1"
             horizontalCenter="0" verticalCenter="1"
             left="10" right="10" top="2" bottom="2" />
 
</s:SparkSkin>

[GoogleAdsWide]

View source is enabled in the following example.

[Squidfingers]

This entry is based on a beta version of the Flex 4 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 4 SDK.

One thought on “Setting a bitmap fill on a Spark Button control in Flex 4

Comments are closed.