Enable Scrolling in the tab bar of a TabbedViewNavigator

The default tab bar in a TabbedViewNavigator sizes its buttons to fit them all into the screen at once truncating where necessary. This post demonstrates how to create a custom skin that doesn’t truncate buttons, but instead allows horizontal scrolling to reveal buttons offscreen.

First we use CSS to set a custom skin on the tab bar and the Scroller inside of it:

Main.mxml:

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                xmlns:s="library://ns.adobe.com/flex/spark">
 
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        s|TabbedViewNavigator #tabBar {
            skinClass: ClassReference("ScrollingTabBarSkin");
        }
        s|TabbedViewNavigator #tabBar s|Scroller {
            skinClass: ClassReference("NoScrollBarScrollerSkin"); 
        }
    </fx:Style>
 
    <s:TabbedViewNavigator id="tvn" width="100%" height="100%" >
        <s:ViewNavigator  label="AAAAAAA" width="100%" height="100%" firstView="views.ViewA"/>
        <s:ViewNavigator label="BBBBBBB" width="100%" height="100%" firstView="views.ViewB"/>
        <s:ViewNavigator label="CCCCCCC" width="100%" height="100%" firstView="views.ViewC"/>
        <s:ViewNavigator label="DDDDDDD" width="100%" height="100%" firstView="views.ViewD"/>
        <s:ViewNavigator label="EEEEEEE" width="100%" height="100%" firstView="views.ViewE"/>
        <s:ViewNavigator label="FFFFFFF" width="100%" height="100%" firstView="views.ViewF"/>
        <s:ViewNavigator label="GGGGGGG" width="100%" height="100%" firstView="views.ViewG"/>
        <s:ViewNavigator label="HHHHHHH" width="100%" height="100%" firstView="views.ViewH"/>
    </s:TabbedViewNavigator>
 
</s:Application>

The next step is to create the ScrollingTabBarSkin. This is a pretty simple subclass of the default TabbedViewNavigatorTabBarSkin that uses a HorizontalLayout and adds the underlying dataGroup to a Scroller:

ScrollingTabBarSkin.as:

package
{
    import mx.core.InteractionMode;
    import spark.components.Scroller;
    import spark.layouts.HorizontalLayout;
    import spark.skins.mobile.TabbedViewNavigatorTabBarSkin;
 
    /**
     *  A custom TabbedViewNavigatorTabBarSkin skin that enables horizontal scrolling in the tab bar.
     */
    public class ScrollingTabBarSkin extends TabbedViewNavigatorTabBarSkin
    {
        public var scroller:Scroller;
 
        /**
         *  Override createChildren() to create a Scroller and add the DataGroup
         *  as its viewport.
         */
        override protected function createChildren():void
        {
            super.createChildren();
 
            // use a standard HorizontalLayout instead of a specialized layout
            var tabLayout:HorizontalLayout = new HorizontalLayout();
            tabLayout.useVirtualLayout = false;
            tabLayout.gap = 0;
 
            dataGroup.layout = tabLayout;
 
            scroller = new Scroller();
            scroller.setStyle('interactionMode', InteractionMode.TOUCH);
            scroller.viewport = dataGroup;
            addChild(scroller);
        }
 
        /** 
         * Size and position the Scroller
         */
        override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void
        {
            setElementPosition(scroller, 0, 0);
            setElementSize(scroller, unscaledWidth, unscaledHeight);
        }
    }
}

Finally you probably don’t want the scrollbars to be shown in this Scroller so here is a custom Scroller skin that doesn’t have any scrollbars.

NoScrollBarScrollerSkin.mxml:

<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark">
 
    <fx:Metadata>
        <![CDATA[ 
            [HostComponent("spark.components.Scroller")]
        ]]>
    </fx:Metadata>
 
    <!-- Removed the HScrollBar and VScrollBar -->
 
</s:SparkSkin>

Note: This sample requires the final release build of Flex 4.5 or later.

8 thoughts on “Enable Scrolling in the tab bar of a TabbedViewNavigator”

  1. This example is working fine for me. but i need to add the buttons to scroll the hidden tabs in the Tabbedviewnavigator’s tab bar. can you pls give me some suggestions…

  2. How can I have the Scroller default to the selected tab? When a user exits the app and comes back, if the selected tab is off screen I need to have the Scroller move/start where the selected tab is. Thank you.

  3. Very nice feature. There is one more element that it needs however. And that is the ability to know if there are more menu items on either the left or the right. Else you may not know that more options exist. Something like either arrows to indicate more items or even some sort of beveled effect on the last visible tab item so that it sugges more options are off screen.

Comments are closed.