Menu

TabbedViewNavigator and TabbedViewNavigatorApplication

SourceForge Editorial Staff

TabbedViewNavigator - Functional and Design Specification


Prerequisites

It is highly recommended that you read the ViewNavigator Specification and ViewNavigatorApplication Specification before reading this document.

Summary and Background

Many mobile applications choose to divide their application into a series of functional application states that can be toggled between through a tab-based user interface. To accommodate this use case, the Flex mobile framework will introduce a new type of application base class, TabbedViewNavigatorApplication, that provides all the functionality and UI affordances needed to create a tab-based application. With this new application type, the framework will also introduce a new type of view navigator, TabbedViewNavigator that manages the navigation state and model of the application. This navigator accepts ViewNavigators as children and provides apis to switch between each. TabbedViewNavigator integrates a ButtonBar UI control that provides the user the ability to switch between the various navigators.

This class will serve as the main application component for application that would like to use a tab-based interface to navigate the root sections of the application. TabbedViewNavigatorApplication will inherit all the functionality of ViewNavigatorApplicationBase, meaning it will automatically integrate with device hardware keys and automatically persist its children's navigator state between application launches.

Goals

  • A container that manages child view navigators
  • An application class that provides standard affordances for tabbed based mobile applications
  • An application class that inherits the persistence and device integration functionality of ViewNavigatorApplication

Non-Goals

  • Support for the "Launch Dashboard" or "Home Page" application metaphor. This can be accomplished with a simple ViewNavigator or ViewNavigatorApplication.

B Features

  • The ability to play a view transition when the tab bar changes (not implemented)
  • The built in mechanism for traversing back history between tabs (not implemented)

Usage Scenarios

Jon has designed an application that is broken down into different modes of operation. He would like each section to be represented by a tab in the application's main chrome, and for each section to maintain its own unique navigation stack. To accomplish this, Jon uses the TabbedViewNavigatorApplication class to populate a TabbedViewNavigator with distinct ViewNavigators. By doing this, Jon can easily use the Flex framework to operate on the different navigation stacks and provide a standard user interface to his users.

Detailed Description

TabbedViewNavigator Component Structure

TabbedViewNavigator is composed of two components. The TabBar and a content container that holds the navigator's children. TabbedViewNavigator only takes other ViewNavigators as children, meaning each child will need to extend ViewNavigatorBase. The TabBar is a skin part that is placed at the bottom of the component by default. It is the interface used to switch between each of TabbedViewNavigator's child navigators. As each child is activated, it will be added to the navigator's content group.

Child Management

TabbedViewNavigator's main role is to manage the visibility of each of its child navigators through a tab interface. TabbedViewNavigator takes other view navigators as children and can be set up by populating the default navigators property with components that extend ViewNavigatorBase. For example:

<s:TabbedViewNavigator>
    <s:ViewNavigator label="Browse" 
        icon="@Embed('assets/browseIcon.png')" 
        firstView="BrowseView"/>

    <s:ViewNavigator label="Favorites" 
        icon="@Embed('assets/favoritesIcon.png')" 
        firstView="FavoritesView"/>
</s:TabbedViewNavigator>

The code above creates a tabbed navigator that has two children. Two tabs will be visible in the tab bar labeled "Browse" and "Favorites" with their respective icons. When the user clicks on a tab, the navigator will switch between the two navigates. To allow the developer to operate on a navigator, TabbedViewNavigator will expose an selectedNavigator property which is a reference to the currently selected navigator. By default, the active navigator will be the first view navigator added to the tabbed navigator. The active navigator is set by changing the selectedIndex on the tab navigator or by clicking a tab on the tab bar.

Managing Selection

The selected navigator can be changed by using the selectedIndex property on TabbedViewNavigator or its tabBar, or by physically clicking on the tab that represents the View. When a new navigator is selected, TabbedViewNavigator will dispatch a IndexChangeEvent.CHANGE to indicate the selection is complete. At this point, the previous view navigator is removed from the display list, and the removed navigator's view history will be cleared. If the developer would like the navigation stack or view instance to remain intact, they will need to extend TabbedViewNavigator or take advantage of some mx_internal methods.

Canceling Navigation
When a new navigator's selected index is about to change, TabbedViewNavigator will dispatch a IndexChangeEvent.CHANGING event. If this event is canceled, the TabbedViewNavigator's selected navigator will remain selected, and the navigation operation will be canceled.

Destruction Policies

TabbedViewNavigator adheres to View.destructionPolicy as described in the ViewNavigator Specification. If a view's destructionPolicy is set to "never", it will never be destroyed by the navigator unless popped off the stack.

ViewNavigatorBase Inherited Functionality

TabbedViewNavigator extends ViewNavigatorBase which is described in the ViewNavigator spec. This allows TabbedViewNavigator to inherit all the base view navigator functionality provided by this base class. This includes support for overlay modes and orientation skin states. These features work exactly the same way as with ViewNavigator, and detailed information about these features is available in the ViewNavigator spec. All child navigators automatically inherit the overlay mode and orientation of the tabbed navigator.

Toggling the TabBar's Visibility

The TabBar of TabbedViewNavigator can be hidden and shown by using apis on the navigator and active view. TabbedViewNavigator has the hideTabBar() and showTabBar() methods that allow an application to toggle the visibility of the tab bar. Each View object also has a tabBarVisible property that can be used to hide and show the tab bar as well.

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        title="Image View"
        tabBarVisible="false"
        actionBarVisible="false">

    <s:Scroller width="100%" height="100%">
        <s:Group>
            <s:BitmapImage source="@Embed('images/img.jpeg')"/>
        </s:Group>
    </s:Scroller>

    <s:Button label="Toggle ActionBar" click="{actionBarVisible = !actionBarVisible}"/>
    <s:Button label="Toggle TabBar" click="{tabBarVisible = !tabBarVisible}"/>
</s:View>

The code above shows a view that hides both the action bar and tab bar when created (tabBarVisible and actionBarVisible are initialized to false). It provides buttons that can be used to toggle the visibility of each ui control. Note that the ActionBar is a child of the ViewNavigator and isn't owned by TabbedViewNavigator. This means that each ViewNavigator child will have its own instance of the action bar. When the tab bar is hidden, its includeInLayout and visible flags are set to false. Custom skins will need to take this into consideration to properly interact with this feature.

Customizing the Hide and Show Effects
Customizing the hide and show effect is identical to that described in the ViewNavigator Specification. The animation played when the tab bar is hidden and shown is controlled by the navigator. A developer can change these by extending TabbedViewNavigator and overriding the createTabBarShowEffect() and createTabBarHideEffect() methods. These methods should return the IEffect animation that should be played by the navigator. When customizing the hide and show animations, keep in mind that it is the developers responsibility to animate the tabBar and the contentGroup skinparts if they exist.

TabbedViewNavigatorApplication

TabbedViewNavigatorApplication is a new application class that employs a tabbed navigation metaphor. It is meant to be used by mobile applications that wish to divide their application into distinct modes of operation. Internally, TabbedViewNavigatorApplication manages a TabbedViewNavigator that can be referenced using the tabbedNavigator property. Children can be added to the tabbed navigator by placing ViewNavigatorBase components in the application tag:

<?xml version="1.0" encoding="utf-8"?>
<s:TabbedViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                           xmlns:s="library://ns.adobe.com/flex/spark"
                           persistNavigatorState="true">
    <s:ViewNavigator width="100%" height="100%" label="Search" firstView="views.SearchView"/>
    <s:ViewNavigator width="100%" height="100%" label="Favorites" firstView="views.FavoritesView"/>
</s:TabbedViewNavigatorApplication>

The code above creates a tabbed mobile application that is broken down into two sections. TabbedViewNavigatorApplication extends ViewNavigatorApplicationBase which means it gains the same orientation, hardware key and persistence integration described in the ViewNavigatorApplication Spec. The slight differences are described below:

Back Key Handling
When the back key is pressed, the event is deferred to the selected navigator of the application. This means the navigator will not support maintaining back history between different tabs. Back operates solely on the active navigator's navigation stack.

Navigator State Persistence
When the persistNavigatorState flag is true, TabbedViewNavigatorApplication will persist the selected index of the application as well as the navigation stack of each child navigator. It is important to note that TabbedViewNavigatorApplication doesn't know how to resolve situations where the order or the number of children changes between application launch and suspension. The component assumes that the same amount of navigators will managed by the application at exit and launch.

API Description

The apis provide by ViewNavigatorBase and ViewNavigatorApplicationBase are detailed in the ViewNavigator and ViewNavigatorApplication Specifications.

ViewNavigatorBase

The the icon and label properties of child navigators are used to display information in the tab bar of the TabbedViewNavigator.

package spark.components.supportClasses
{
public class ViewNavigatorBase extends SkinnableContainer
{
    /**
     *  Returns the icon that should be used when this navigator is represented
     *  by a visual component.
     *
     *  @default null
     */
    public function get icon():Object;
    public function set icon(value:Class):Object;

    <a href="Bindable">Bindable</a>
    /**
     *  The label to be used when this stack is represented by a visual component.
     *
     *  @default null
     */
    public function get label():String;
    public function set label(value:String):void;
}
}

TabbedViewNavigator

package spark.components
{
<a href="DefaultProperty%28%26quot%3Bnavigators%26quot%3B%29">DefaultProperty("navigators")</a>

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched when the selected index of the navigator changes.
 */
<a href="Event%28name%3D%26quot%3Bchange%26quot%3B%2C%20type%3D%26quot%3Bspark.events.IndexChangeEvent%26quot%3B%29">Event(name="change", type="spark.events.IndexChangeEvent")</a>

/**
 *  A cancelable event that is dispatched before the selected index
 *  of the navigator changes.
 */
<a href="Event%28name%3D%26quot%3Bchanging%26quot%3B%2C%20type%3D%26quot%3Bspark.events.IndexChangeEvent%26quot%3B%29">Event(name="changing", type="spark.events.IndexChangeEvent")</a>

/**
 *  Dispatched when the collection of view navigators managed by the
 *  TabbedViewNavigator changes.
 */
<a href="Event%28name%3D%26quot%3BcollectionChange%26quot%3B%2C%20type%3D%26quot%3Bmx.events.CollectionEvent%26quot%3B%29">Event(name="collectionChange", type="mx.events.CollectionEvent")</a>

/**
 *  Dispatched when the view navigator's selected index changes.  
 *  When this event is dispatched, the <code>selectedIndex</code> 
 *  and <code>activeNavigator</code> properties reference the 
 *  newly selected view navigator.
 */
<a href="Event%28name%3D%26quot%3BvalueCommit%26quot%3B%2C%20type%3D%26quot%3Bmx.events.FlexEvent%26quot%3B%29">Event(name="valueCommit", type="mx.events.FlexEvent")</a>

public class TabbedViewNavigator extends ViewNavigatorBase implements ISelectableList
{
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    public function TabbedViewNavigator();

    //--------------------------------------------------------------------------
    //
    //  Skin Parts
    //
    //--------------------------------------------------------------------------

    /**
     *  A skin part that defines the tab bar of the navigator.
     */
    <a href="Bindable">Bindable</a>
    <a href="SkinPart%28required%3D%26quot%3Bfalse%26quot%3B%29">SkinPart(required="false")</a>
    public var tabBar:ButtonBarBase;

    //--------------------------------------------------------------------------
    //
    // Properties
    //
    //--------------------------------------------------------------------------

    /**
     *  A reference to the active navigator of the tabbed navigator.
     *  This will be the child that resides at the selected index
     *  of the navigators array.
     *
     *  @default null
     */
    <a href="Bindable%28%26quot%3Bchange%26quot%3B%29">Bindable("change")</a>
    public function get selectedNavigator():ViewNavigatorBase;

    <a href="ArrayElementType%28%26quot%3Bspark.components.ViewNavigatorBase%26quot%3B%29">ArrayElementType("spark.components.ViewNavigatorBase")</a>
    /**
     *  The child navigators of the view navigator.
     */
    public function get navigators():Vector.<ViewNavigatorBase>;
    public function set navigators(value:Vector.<ViewNavigatorBase>):void;

    //--------------------------------------------------------------------------
    //
    // Public Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  Hides the tab bar of the navigator.
     *
     *  @param animate Flag indicating whether a hide effect should play.
     *  True by default.
     */
    public function hideTabBar(animate:Boolean = true):void;

    /**
     *  Shows the tab bar of the navigtor
     *
     *  @param animate Flag indicating whether a hide effect should play.
     *  True by default.
     */
    public function showTabBar(animate:Boolean = true):void

    /**
     *  This method is responsible for updating the selection when
     *  the desired selected index changes through the use of the
     *  tab bar or selectedIndex property.
     */
    protected function commitSelection():void;

    /**
     *  Creates the effect to play when the TabBar control is shown.
     *  The produced effect is responsible for animating both the 
     *  TabBar and the content group of the navigator.
     * 
     *  <p>TabbedViewNavigator will expect the <code>includeInLayout</code>
     *  and <code>visible</code> properties of the tabBar to be true
     *  after this effect is run.</p>
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.1
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected function createTabBarShowEffect():IEffect;

    /**
     *  Creates the effect to play when the TabBar control is hidden.
     *  The produced effect is responsible for animating both the 
     *  TabBar and the content group of the navigator.
     * 
     *  <p>TabbedViewNavigator will expect the <code>includeInLayout</code>
     *  and <code>visible</code> properties of the tabBar to be false
     *  after this effect is run.</p>
     * 
     *  @return An effect to play when the TabBar control is hidden.
     *  @langversion 3.0
     *  @playerversion Flash 10.1
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected function createTabBarHideEffect():IEffect;

    //--------------------------------------------------------------------------
    //
    //  Methods: ISelectableList
    //
    //--------------------------------------------------------------------------

    <a href="Bindable%28%26quot%3Bchange%26quot%3B%29">Bindable("change")</a>
    <a href="Bindable%28%26quot%3BvalueCommit%26quot%3B%29">Bindable("valueCommit")</a>
    /**
     *  Returns the selected index of the navigator
     */
    public function get selectedIndex():int
    public function set selectedIndex(value:int):void;

    // TabbedViewNavigator also supports all other IList apis
}
}

TabbedViewNavigatorApplication

package spark.components
{
<a href="DefaultProperty%28%26quot%3Bnavigators%26quot%3B%29">DefaultProperty("navigators")</a>

public class TabbedViewNavigatorApplication extends ViewNavigatorApplicationBase
{
    //--------------------------------------------------------------------------
    //
    //  Skin Parts
    //
    //--------------------------------------------------------------------------

    /**
     *  The main navigator for the application.
     */
    <a href="SkinPart%28required%3D%26quot%3Bfalse%26quot%3B%29">SkinPart(required="false")</a>
    public var tabbedNavigator:TabbedViewNavigator;

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    public function TabbedViewNavigatorApplication();

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    <a href="ArrayElementType%28%26quot%3Bspark.components.ViewNavigatorBase%26quot%3B%29">ArrayElementType("spark.components.ViewNavigatorBase")</a>
    /**
     *  The child navigators managed by the application.
     */
    public function get navigators():Vector.<ViewNavigatorBase>;
    public function set navigators(value:Vector.<ViewNavigatorBase>):void;
}
}

View

The following apis will be added to View to support this component.

package spark.components
{
public class View extends Group
{
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     *  Flag indicating whether the tab bar is visible or not.
     *
     *  @default true
     */
    public function get tabBarVisible():Boolean;
    public function set tabBarVisible(value:Boolean):void;

}
}

TabbedViewNavigatorSkin

The skin for the TabbedViewNavigator.

package spark.skins.mobile
{

public class TabbedViewNavigatorSkin extends MobileSkin
{
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    /**
     *  Constructor.
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5 
     *  @productversion Flex 4.5
     * 
     */
    public function TabbedViewNavigatorSkin();

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------
    /** 
     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
    public var hostComponent:TabbedViewNavigator;

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     *  @copy spark.components.SkinnableContainer#contentGroup
     */
    public var contentGroup:Group;

    /**
     *  @copy spark.components.TabbedViewNavigator#tabBar
     */
    public var tabBar:ButtonBarBase;
}

TabbedViewNavigatorApplicationSkin

Skin for the TabbedViewNavigatorApplication.

package spark.skins.mobile
{

/**
 *  The ActionScript-based skin used for TabbedViewNavigatorApplication.  
 *  This skin contains a single TabbedViewNavigator that spans the
 *  entire content area of the application.
 * 
 * @see spark.components.TabbedViewNavigatorApplication
 * 
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5 
 *  @productversion Flex 4.5
 */
public class TabbedViewNavigatorApplicationSkin extends MobileSkin
{
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function TabbedViewNavigatorApplicationSkin();

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     * The navigator for the application
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public var tabbedNavigator:TabbedViewNavigator;


    /**
     *  Creates an action menu from this factory when the menu button is pressed 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */ 
    public var viewMenu:IFactory;

    /** 
     *  @copy spark.skins.spark.ApplicationSkin#hostComponent
     */
    public var hostComponent:TabbedViewNavigatorApplication;
}

Examples and Usage

The following example creates a TabbedViewNavigatorApplication that automatically persists its application state. It creates two navigators that each manage their own set of apis.

<?xml version="1.0" encoding="utf-8"?>
<s:TabbedViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                           xmlns:s="library://ns.adobe.com/flex/spark"
                           persistNavigatorState="true">
    <s:ViewNavigator width="100%" height="100%" label="Search" firstView="views.SearchView"/>
    <s:ViewNavigator width="100%" height="100%" label="Favorites" firstView="views.FavoritesView"/>
</s:TabbedViewNavigatorApplication>

\

Additional Implementation Details

\

Compiler Work

\

Performance

\

Issues and Recommendations


Related

Wiki: Flex 4.5
Wiki: View and ViewNavigator
Wiki: ViewNavigatorApplication

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.