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 http://www.adobe.com/products/flex/. To download the latest nightly build of the Flex 4 SDK, see http://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.

 
Tagged with:
 
About The Author

Peter deHaan

Peter deHaan currently works for Adobe on the Flex SDK QA team. While not working on Flex, Flash, and ColdFusion applications, Peter enjoys making up bios and writing in 3rd person. Peter's rarely updated blog can be found at blogs.adobe.com/pdehaan/, actionscriptexamples.com, airexamples.com, and coldfusionexamples.com.

6 Responses to Removing the selected highlight from the Spark ButtonBar control in Flex 4

  1. Peter deHaan says:

    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. Anonymous says:

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

    Error: Required skin part middleButton cannot be found.

  3. Ilya Gazman says:

    You should fix the Metadata at the costumButtonBarSkin to look like this:

  4. itnix says:

    Flex4 makes me puke… it’s the worst framework made ever!

  5. Marcus says:

    thanks Peter for the callLater example

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Anti-Spam Protection by WP-SpamFree