Removing the selected highlight from the Spark ButtonBar control in Flex 4

The following example shows how you can remove the selected highlight from the Spark ButtonBar control in Flex 4 by creating a custom ButtonBar and ButtonBarButton skin class.

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/03/31/removing-the-selected-highlight-from-the-spark-buttonbar-control-in-flex-4/ -->
<s:Application name="Spark_ButtonBar_unselectable_test"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark">
    <s:controlBarContent>
        <s:Label text="selectedIndex: {btnBar.selectedIndex}" />
    </s:controlBarContent>
 
    <s:ButtonBar id="btnBar"
            labelField="label"
            skinClass="skins.CustomButtonBarSkin"
            horizontalCenter="0" verticalCenter="0">
        <s:dataProvider>
            <s:ArrayList>
                <fx:Object label="Red" />
                <fx:Object label="Orange" />
                <fx:Object label="Yellow" />
                <fx:Object label="Green" />
                <fx:Object label="Blue" />
            </s:ArrayList>
        </s:dataProvider>
    </s:ButtonBar>
 
</s:Application>

The custom Spark ButtonBar skin, skins/CustomButtonBarSkin.mxml, is as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/03/31/removing-the-selected-highlight-from-the-spark-buttonbar-control-in-flex-4/ -->
<s:Skin name="CustomButtonBarSkin"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark" 
        alpha.disabled="0.5">
    <s:states>
        <s:State name="normal" />
        <s:State name="disabled" />
    </s:states>
 
    <fx:Metadata>
        [HostComponent("spark.components.ButtonBar")]
    </fx:Metadata> 
 
    <fx:Declarations>
        <fx:Component id="middleButton" >
            <s:ButtonBarButton skinClass="skins.CustomButtonBarMiddleButtonSkin" />
        </fx:Component>
    </fx:Declarations>
 
    <s:DataGroup id="dataGroup" width="100%" height="100%">
        <s:layout>
            <s:ButtonBarHorizontalLayout gap="-1"/>
        </s:layout>
    </s:DataGroup>
 
</s:Skin>

And the custom Spark ButtonBarButton skin, skins/CustomButtonBarMiddleButtonSkin.mxml, is as follows:

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2010/03/31/removing-the-selected-highlight-from-the-spark-buttonbar-control-in-flex-4/ -->
<s:SparkSkin name="CustomButtonBarMiddleButtonSkin"
        xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        minWidth="21" minHeight="21"
        alpha.disabledStates="0.5">
    <!-- states -->
    <s:states>
        <s:State name="up" />
        <s:State name="over" stateGroups="overStates" />
        <s:State name="down" stateGroups="downStates" />
        <s:State name="disabled" stateGroups="disabledStates" />
        <s:State name="upAndSelected" stateGroups="selectedStates, selectedUpStates" />
        <s:State name="overAndSelected" stateGroups="overStates, selectedStates" />
        <s:State name="downAndSelected" stateGroups="downStates, selectedStates" />
        <s:State name="disabledAndSelected" stateGroups="selectedUpStates, disabledStates, selectedStates" />
    </s:states>
 
    <fx:Script>
        <![CDATA[
            override protected function initializationComplete():void {
                useChromeColor = true;
                super.initializationComplete();
            }
        ]]>
    </fx:Script>
 
    <!-- layer 1: shadow -->
    <s:Rect left="0" right="0" bottom="-1" height="1">
        <s:fill>
            <s:SolidColor color="0x000000"
                color.downStates="0xFFFFFF"
                alpha="0.07"
                alpha.downStates="0.5" />
        </s:fill>
    </s:Rect>
 
    <!-- layer 2: fill -->
    <s:Rect left="1" right="1" top="1" bottom="1">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0xFFFFFF"
                        color.overStates="0xBBBDBD"
                        color.downStates="0xAAAAAA"
                        alpha="0.85" />
                <s:GradientEntry color="0xD8D8D8"
                        color.over="0x9FA0A1"
                        color.downStates="0x929496"
                        alpha="0.85" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>
 
    <!-- layer 3: fill lowlight -->
    <s:Rect left="1" right="1" top="1" bottom="1">
        <s:fill>
            <s:LinearGradient rotation="270">
                <s:GradientEntry color="0x000000"
                        ratio="0.0"
                        alpha="0.0627" />
                <s:GradientEntry color="0x000000"
                        ratio="0.48"
                        alpha="0.0099" />
                <s:GradientEntry color="0x000000"
                        ratio="0.48001"
                        alpha="0" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>
 
    <!-- layer 4: fill highlight -->
    <s:Rect left="1" right="1" top="1" bottom="1">
        <s:fill>
            <s:LinearGradient rotation="90">
                <s:GradientEntry color="0xFFFFFF"
                        ratio="0.0"
                        alpha="0.33"
                        alpha.overStates="0.22"
                        alpha.downStates="0.12"/>
                <s:GradientEntry color="0xFFFFFF"
                        ratio="0.48"
                        alpha="0.33"
                        alpha.overStates="0.22"
                        alpha.downStates="0.12"/>
                <s:GradientEntry color="0xFFFFFF"
                        ratio="0.48001"
                        alpha="0" />
            </s:LinearGradient>
        </s:fill>
    </s:Rect>
 
    <!-- layer 5: highlight stroke (all states except down) -->
    <s:Rect left="1" right="1" top="1" bottom="1" excludeFrom="downStates">
        <s:stroke>
            <s:LinearGradientStroke rotation="90" weight="1">
                <s:GradientEntry color="0xFFFFFF"
                        alpha.overStates="0.22" />
                <s:GradientEntry color="0xD8D8D8"
                        alpha.overStates="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"
        includeIn="downStates">
        <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"
        includeIn="downStates">
        <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 left="0" right="0" top="0" bottom="0"
            width="69" height="20">
        <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>

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.

6 thoughts on “Removing the selected highlight from the Spark ButtonBar control in Flex 4

  1. Another solution that wouldn’t require reskinning would be to listen for the change event and then use the callLater() function to set the selectedIndex property to -1, as seen in the following example:

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">
     
        <fx:Script>
            <![CDATA[
                import spark.events.IndexChangeEvent;
     
                protected function clearSel():void {
                    lst1.selectedIndex = -1;
                }
     
                protected function lst1_changeHandler(evt:IndexChangeEvent):void {
                    callLater(clearSel);
                }
            ]]>
        </fx:Script>
     
        <s:ButtonBar id="lst1"
                     change="lst1_changeHandler(event);"
                     x="20" y="20">
            <s:dataProvider>
                <s:ArrayList source="[One,Two,Three,Four,Five,Six]" />
            </s:dataProvider>
        </s:ButtonBar>
        <s:Label text="{lst1.selectedIndex}" />
     
    </s:Application>

    Peter

  2. I am getting an error when I am trying the first version:

    Error: Required skin part middleButton cannot be found.

Comments are closed.