Styling individual tabs in a TabBar control

The following example shows how you can style individual tabs in a Flex TabBar control by calling the getChildAt() method on the tab bar, and then calling setStyle() on the returned Tab reference.

A big thanks to Joan for helping me figure it out.

Full code after the jump.

<?xml version="1.0"?>
<!-- http://blog.flexexamples.com/2007/11/19/styling-individual-tabs-in-a-tabbar-control/ -->
<mx:Application name="TabBar_getChildAt_test"
        xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white">
 
    <mx:Script>
    <![CDATA[
        import mx.events.ItemClickEvent;
        import mx.controls.tabBarClasses.Tab;
 
        private function tabBar_creationComplete():void {
            var colorArr:Array = ["red", "haloOrange", "yellow", "haloGreen", "haloBlue"];
            var color:String;
            var tab:Tab;
            var idx:uint;
            var len:uint = tabBar.dataProvider.length;
 
            for (idx = 0; idx < len; idx++) {
                var i:int = idx % colorArr.length;
                color = colorArr[i];
                tab = Tab(tabBar.getChildAt(idx));
                tab.setStyle("fillColors", [color, "white"]);
                tab.setStyle("fillAlphas", [1.0, 1.0]);
                tab.setStyle("backgroundColor", color);
            }
        }
 
        private function tabBar_itemClick(evt:ItemClickEvent):void {
            viewStack.selectedIndex = evt.index;
        }
    ]]>
    </mx:Script>
 
    <mx:Array id="arr">
        <mx:Object label="Red" />
        <mx:Object label="Orange" />
        <mx:Object label="Yellow" />
        <mx:Object label="Green" />
        <mx:Object label="Blue" />
    </mx:Array>
 
    <mx:TabBar id="tabBar"
            dataProvider="{arr}"
            creationComplete="tabBar_creationComplete();"
            itemClick="tabBar_itemClick(event);" />
 
    <mx:ViewStack id="viewStack"
            width="{tabBar.width}"
            styleName="plain">
        <mx:VBox id="redVBox" width="100%" height="100">
            <mx:Label text="Red VBox" />
        </mx:VBox>
        <mx:VBox id="orangeVBox" width="100%" height="100">
            <mx:Label text="Orange VBox" />
        </mx:VBox>
        <mx:VBox id="yellowVBox" width="100%" height="100">
            <mx:Label text="Yellow VBox" />
        </mx:VBox>
        <mx:VBox id="greenVBox" width="100%" height="100">
            <mx:Label text="Green VBox" />
        </mx:VBox>
        <mx:VBox id="blueVBox" width="100%" height="100">
            <mx:Label text="Blue VBox" />
        </mx:VBox>
    </mx:ViewStack>
 
</mx:Application>

View source is enabled in the following example.

14 thoughts on “Styling individual tabs in a TabBar control

  1. I can’t seem to get this to work. I’m using Flex 3 and Flash player 10.0. When I copy and paste the code verbatim into Flex builder and run it, I get a gray box with text-only tabs (no colors, no boarders, nothing). Any ideas?

  2. How do we change the color of the text on the tab itself? I see stuff for the body of a tab, but not the tab header …

    1. @Shannara,

      If you want to use the same text color for each tab you can set the color style in the MXML directly, as seen in the following snippet:

      <mx:TabBar id="tabBar"
              dataProvider="{arr}"
              color="white"
              creationComplete="tabBar_creationComplete();"
              itemClick="tabBar_itemClick(event);" />

      Or if you want a separate text colors for each tab you can set the color style using ActionScript, as seen in the following example:

      tab.setStyle("color", Math.random() * 0xFFFFFF);

      Peter

  3. In this example the tabs are already instantiated when calling tabBar.getChildAt(idx). However when adding tab pages dynamically the getChildAt often causes an error because the tabs haven’t been set up yet. This makes it rather problematic to set properties (visible…) or styles.

  4. This example works in this page, but when I run it in Flashbuilder 4, it does not work. I get the tabs but no color.

    1. @Richard,

      Try something like this instead:

       
      <?xml version="1.0"?>
      <s:Application name="TabBar_getChildAt_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:layout>
              <s:VerticalLayout horizontalAlign="center" verticalAlign="middle" />
          </s:layout>
       
          <fx:Script>
              <![CDATA[
                  import mx.events.ItemClickEvent;
                  import mx.controls.tabBarClasses.Tab;
       
                  private function tabBar_creationComplete():void {
                      const colorArr:Array = ["red", "haloOrange", "yellow", "haloGreen", "haloBlue"];
                      var color:String;
                      var tab:Tab;
                      var idx:uint;
                      const len:uint = tabBar.dataProvider.length;
       
                      for (idx = 0; idx < len; idx++) {
                          var i:int = idx % colorArr.length;
                          color = colorArr[i];
                          tab = Tab(tabBar.getChildAt(idx));
                          tab.setStyle("chromeColor", color);
                      }
                  }
       
                  private function tabBar_itemClick(evt:ItemClickEvent):void {
                      viewStack.selectedIndex = evt.index;
                  }
              ]]>
          </fx:Script>
       
          <mx:TabBar id="tabBar"
                  creationComplete="tabBar_creationComplete();"
                  itemClick="tabBar_itemClick(event);">
              <mx:dataProvider>
                  <fx:Array id="arr">
                      <fx:Object label="Red" />
                      <fx:Object label="Orange" />
                      <fx:Object label="Yellow" />
                      <fx:Object label="Green" />
                      <fx:Object label="Blue" />
                  </fx:Array>
              </mx:dataProvider>
          </mx:TabBar>
       
          <mx:ViewStack id="viewStack"
                  width="{tabBar.width}"
                  styleName="plain">
              <mx:VBox id="redVBox" width="100%" height="100">
                  <mx:Label text="Red VBox" />
              </mx:VBox>
              <mx:VBox id="orangeVBox" width="100%" height="100">
                  <mx:Label text="Orange VBox" />
              </mx:VBox>
              <mx:VBox id="yellowVBox" width="100%" height="100">
                  <mx:Label text="Yellow VBox" />
              </mx:VBox>
              <mx:VBox id="greenVBox" width="100%" height="100">
                  <mx:Label text="Green VBox" />
              </mx:VBox>
              <mx:VBox id="blueVBox" width="100%" height="100">
                  <mx:Label text="Blue VBox" />
              </mx:VBox>
          </mx:ViewStack>
       
      </s:Application>

      Peter

      1. Yee, the code with chromoColor is working, but: its only make one color, not the nice color transition. Tested as: tab.setStyle(“chromeColor”, [color, “white”]); …how to correct this?

  5. Is there a way to set individual tab colors with the Spark TabBar ? The getChildAt(idx) returns a skin in the Spark TabBar.

    1. same problem for me, any ideas? i’ve googled for a week now…. the only solutions are similar to this, but nothing about TabNavigator and tabBar, the Flash Builder 4.5 even doesn’t list mx.controls.tabBarClasses.Tab among context help…
      Really Thanks in advance.

    2. Found a sort of solution finally:
      if you have:


      and the following AS code:

      protected function click_but2(event:MouseEvent):void
      {
      var box:NavigatorContent = new NavigatorContent;
      box.label = "Child " + navigator.numChildren;
      box.addEventListener(FlexEvent.CREATION_COMPLETE,tabCreationComplete);
      navigator.addChild(box);
      }

      private function tabCreationComplete(event:FlexEvent):void{
      navigator.getTabAt(navigator.numChildren -1).styleName="myTabCSSSelector";
      }

      and the following style section

      @namespace s "library://ns.adobe.com/flex/spark";
      @namespace mx "library://ns.adobe.com/flex/mx";
      .myTabCSSSelector{
      color:Yellow;
      chromeColor:Navy;
      }


      this works BUT, if you click a second time the button the previuously created tab reverts its styleName property to the default “ButtonBarButton” value.
      Debugging a bit deeper it seems that after the creation complete of the new tab and after the addChild method there is a re-drawing of the “hidden” tabBar of the TabNavigator which reverts every tab to its default…..
      If some tester (better then me) can find out which is the problem maybe we could find a solution.
      Thanks

      1. half of my post has been cut off….
        i’ll try again (a preview would be great….)

        Found a sort of solution finally:
        if you have:

        
        	
        	
        
        
        

        and the following AS code:

        protected function click_but2(event:MouseEvent):void
        {
        	var box:NavigatorContent = new NavigatorContent;
        	box.label = "Child " + navigator.numChildren;
        	box.addEventListener(FlexEvent.CREATION_COMPLETE,tabCreationComplete);
        	navigator.addChild(box);
        }
        
        private function tabCreationComplete(event:FlexEvent):void{
        	navigator.getTabAt(navigator.numChildren -1).styleName="myTabCSSSelector";
        }
        

        and the following style section

        
        	@namespace s "library://ns.adobe.com/flex/spark";
        	@namespace mx "library://ns.adobe.com/flex/mx";
        	.myTabCSSSelector{
        		color:Yellow;
        		chromeColor:Navy;
        	}
        
        

        this works BUT, if you click a second time the button the previuously created tab reverts its styleName property to the default “ButtonBarButton” value.
        Debugging a bit deeper it seems that after the creation complete of the new tab and after the addChild method there is a re-drawing of the “hidden” tabBar of the TabNavigator which reverts every tab to its default…..
        If some tester (better then me) can find out which is the problem maybe we could find a solution.
        Thanks

Comments are closed.