You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ti...@apache.org on 2012/01/13 00:15:19 UTC

svn commit: r1230830 [2/4] - in /incubator/flex/whiteboard/tink/iview: ./ examples/ examples/libs/ examples/src/ src/ src/org/ src/org/apache/ src/org/apache/spark/ src/org/apache/spark/components/ src/org/apache/spark/components/supportClasses/ src/or...

Added: incubator/flex/whiteboard/tink/iview/src/org/apache/spark/components/ViewNavigator.as
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/tink/iview/src/org/apache/spark/components/ViewNavigator.as?rev=1230830&view=auto
==============================================================================
--- incubator/flex/whiteboard/tink/iview/src/org/apache/spark/components/ViewNavigator.as (added)
+++ incubator/flex/whiteboard/tink/iview/src/org/apache/spark/components/ViewNavigator.as Thu Jan 12 23:15:17 2012
@@ -0,0 +1,2496 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  ADOBE SYSTEMS INCORPORATED
+//  Copyright 2010 Adobe Systems Incorporated
+//  All Rights Reserved.
+//
+//  NOTICE: Adobe permits you to use, modify, and distribute this file
+//  in accordance with the terms of the license agreement accompanying it.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+package org.apache.spark.components
+{
+	
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.net.registerClassAlias;
+	
+	import mx.core.IVisualElement;
+	import mx.core.UIComponent;
+	import mx.core.mx_internal;
+	import mx.effects.IEffect;
+	import mx.effects.Parallel;
+	import mx.events.EffectEvent;
+	import mx.events.FlexEvent;
+	import mx.events.PropertyChangeEvent;
+	import mx.managers.LayoutManager;
+	
+	import org.apache.spark.components.supportClasses.NavigationStack;
+	import org.apache.spark.components.supportClasses.ViewDescriptor;
+	import org.apache.spark.components.supportClasses.ViewNavigatorBase;
+	import org.apache.spark.transitions.SlideViewTransition;
+	import org.apache.spark.transitions.ViewTransitionBase;
+	
+	import spark.components.ActionBar;
+	import spark.components.supportClasses.ViewNavigatorAction;
+	import spark.components.supportClasses.ViewReturnObject;
+	import spark.core.ContainerDestructionPolicy;
+	import spark.effects.Animate;
+	import spark.effects.animation.Animation;
+	import spark.effects.animation.MotionPath;
+	import spark.effects.animation.SimpleMotionPath;
+	import spark.layouts.supportClasses.LayoutBase;
+	import spark.transitions.ViewTransitionDirection;
+	
+	use namespace mx_internal;
+	
+	[DefaultProperty("navigationStack")]
+	
+	//--------------------------------------
+	//  SkinStates
+	//--------------------------------------
+	
+	/**
+	 *  The state used when the navigator is in portrait orientation.
+	 *  
+	 *  @langversion 3.0
+	 *  @playerversion AIR 2.5
+	 *  @productversion Flex 4.5
+	 */
+	[SkinState("portrait")]
+	
+	/**
+	 *  The state used when the navigator is in landscape orientation.
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion AIR 2.5
+	 *  @productversion Flex 4.5
+	 */
+	[SkinState("landscape")]
+	
+	/**
+	 *  The state used when the navigator is in portrait orientation
+	 *  and the navigator controls are overlaid on top.
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion AIR 2.5
+	 *  @productversion Flex 4.5
+	 */
+	[SkinState("portraitAndOverlay")]
+	
+	/**
+	 *  The state used when the navigator is in landscape orientation
+	 *  and the navigator controls are overlaid on top.
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion AIR 2.5
+	 *  @productversion Flex 4.5
+	 */
+	[SkinState("landscapeAndOverlay")]
+	
+	//--------------------------------------
+	//  Other metadata
+	//--------------------------------------
+	
+	[IconFile("ViewNavigator.png")]
+	
+	/**
+	 *  The ViewNavigator component is a container that consists of a collection of
+	 *  IView objects, where only the top most view is visible and active.  
+	 *  Use the ViewNavigator container to control the navigation among 
+	 *  the views of a mobile application.
+	 *  The ViewNavigatorApplication container automatically creates a 
+	 *  single ViewNavigator container for the entire application.
+	 *  
+	 *  <p>Navigation in a mobile application is controlled by a stack of IView objects. 
+	 *  The top IView object on the stack defines the currently visible view. 
+	 *  The ViewNavigator container maintains the stack. 
+	 *  To change views, push a new IView object onto the stack, 
+	 *  or pop the current IView object off of the stack. 
+	 *  Popping the currently visible IView object from the stack destroys 
+	 *  the IView object, and returns the user to the previous view on the stack.</p>
+	 *
+	 *  <p>When a view is pushed on top of the stack, the old view's <code>data</code> 
+	 *  property is automatically persisted.
+	 *  It is restored when the view is reactived as a result of 
+	 *  the current view being popped off the stack.
+	 *  When a new view becomes active by being pushed onto the stack, 
+	 *  the old view's instance is destroyed.</p>
+	 * 
+	 *  <p>The ViewNavigator displays an optional ActionBar control that displays contextual
+	 *  information defined by the active view.  
+	 *  When the active view changes, the action bar is automatically updated.</p>
+	 *
+	 *  @mxml
+	 *  
+	 *  <p>The <code>&lt;s:ViewNavigator&gt;</code> tag inherits all of the tag 
+	 *  attributes of its superclass and adds the following tag attributes:</p>
+	 *  
+	 *  <pre>
+	 *  &lt;s:ViewNavigator
+	 *   <strong>Properties</strong>
+	 *    actionContent="null"
+	 *    actionLayout="null"
+	 *    defaultPopTransition="SlideViewTransition"
+	 *    defaultPushTransition="SlideViewTransition"
+	 *    firstView="null"
+	 *    firstViewData="null"
+	 *    navigationContent="null"
+	 *    navigationLayout="null"
+	 *    poppedViewReturnedObject="null"
+	 *    title=""
+	 *    titleContent="null"
+	 *    titleLayout="null"
+	 * 
+	 *  &gt;
+	 *  </pre>
+	 *  
+	 *  @see spark.components.IView
+	 *  @see spark.components.ActionBar
+	 *  @see spark.components.TabbedViewNavigator
+	 *  @see spark.transitions.ViewTransitionBase
+	 *
+	 *  @includeExample examples/ViewNavigatorExample.mxml -noswf
+	 *  @includeExample examples/ViewNavigatorExampleHomeView.mxml -noswf
+	 *  @includeExample examples/ViewNavigatorExampleSearch.mxml -noswf
+	 * 
+	 *  @langversion 3.0
+	 *  @playerversion AIR 2.5
+	 *  @productversion Flex 4.5
+	 */
+	public class ViewNavigator extends ViewNavigatorBase
+	{
+		//--------------------------------------------------------------------------
+		//
+		//  Class variables
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 *  The animation duration used when hiding and showing the action bar.
+		 */ 
+		private static const ACTION_BAR_ANIMATION_DURATION:Number = 250;
+		
+		/**
+		 *  @private
+		 *  The animation duration used when running a default view transition.
+		 */     
+		private static const DEFAULT_VIEW_TRANSITION_DURATION:Number = 300;
+		
+		/**
+		 *  @private
+		 *  Flag indicating whether the classes required for the PersistenceManager
+		 *  have been registered with the player.
+		 */
+		private static var classAliasesRegistered:Boolean = false;
+		
+		/**     
+		 *  @private
+		 */
+		private static var viewTransitionSuspendCount:int = 0;
+		private static var eventDispatcher:EventDispatcher;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Constructor
+		//
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Constructor.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function ViewNavigator()
+		{
+			super();
+			
+			if (!classAliasesRegistered)
+			{
+				// Register aliases for custom classes that will be written to
+				// persistence store by navigator
+				registerClassAlias("ViewDescriptor", ViewDescriptor);
+				registerClassAlias("NavigationStack", NavigationStack);
+				
+				classAliasesRegistered = true;
+			}
+			
+			// Default view transitions
+			var slideLeft:org.apache.spark.transitions.SlideViewTransition = new org.apache.spark.transitions.SlideViewTransition();
+			slideLeft.duration = DEFAULT_VIEW_TRANSITION_DURATION;
+			slideLeft.direction = ViewTransitionDirection.LEFT;
+			defaultPushTransition = slideLeft;
+			
+			var slideRight:org.apache.spark.transitions.SlideViewTransition = new org.apache.spark.transitions.SlideViewTransition();
+			slideRight.duration = DEFAULT_VIEW_TRANSITION_DURATION;
+			slideRight.direction = ViewTransitionDirection.RIGHT;
+			defaultPopTransition = slideRight;
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Skin Parts
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------------
+		// Navigator Controls
+		//----------------------------------------
+		
+		[SkinPart(required="false")]    
+		
+		/**
+		 *  A skin part that defines the action bar of the navigator. 
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public var actionBar:ActionBar;
+		
+		//--------------------------------------------------------------------------
+		//
+		// Variables
+		// 
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 */ 
+		private var actionBarProps:Object;
+		
+		/**
+		 *  @private
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */ 
+		private function get actionBarPropertyInvalidated():Boolean
+		{
+			return  actionContentInvalidated ||
+				actionLayoutInvalidated ||
+				navigationContentInvalidated ||
+				navigationLayoutInvalidated ||
+				titleInvalidated ||
+				titleContentInvalidated ||
+				titleLayoutInvalidated ||
+				overlayControlsInvalidated;
+		}
+		
+		/**
+		 *  @private
+		 *  The show/hide effect that is currently being played on the action bar. 
+		 */
+		private var actionBarVisibilityEffect:IEffect;
+		
+		/**
+		 *  @private
+		 */ 
+		private var contentGroupProps:Object;
+		
+		/**
+		 *  @private
+		 *  Internal flag used to track whether a show/hide effect should be
+		 *  played when the action bar visibility is updated.
+		 */ 
+		private var animateActionBarVisbility:Boolean = false;
+		
+		/**
+		 *  @private
+		 *  Flag indicating the that actionBar visiblity has been invalidated
+		 *  by the active view. 
+		 */
+		private var actionBarVisibilityInvalidated:Boolean = false;
+		
+		/**
+		 *  @private
+		 *  Flag indicates that the backKey handler has run and the navigator
+		 *  is waiting a validation pass.
+		 */
+		private var backKeyWasPressed:Boolean = false;
+		
+		/**
+		 *  @private
+		 *  The view data for the active view.
+		 */
+		private var currentViewDescriptor:org.apache.spark.components.supportClasses.ViewDescriptor = null;
+		
+		/**
+		 *  @private
+		 */ 
+		private var delayedNavigationActions:Vector.<Object> = new Vector.<Object>();
+		
+		/**
+		 *  @private
+		 *  Flag indicates that the navigator has been requested to show
+		 *  a different view. 
+		 */
+		mx_internal var viewChangeRequested:Boolean = false;
+		
+		/**
+		 *  @private
+		 */ 
+		private var emptyViewDescriptor:org.apache.spark.components.supportClasses.ViewDescriptor = null;
+		
+		/**
+		 *  @private
+		 *  Variable used to count how many enterframes the navigator has
+		 *  received after preparing a transition.
+		 */ 
+		private var enterFrameCount:int = 0;
+		
+		/**
+		 *  @private
+		 *  This following property stores the <code>mouseEnabled</code>
+		 *  value defined on the navigator so that it can be
+		 *  restored after a view transition.
+		 */
+		private var explicitMouseEnabled:Boolean;
+		
+		/**
+		 *  @private
+		 *  This following property stores the <code>mouseChildren</code>
+		 *  value defined on the navigator so that it can be
+		 *  restored after a view transition.
+		 */
+		private var explicitMouseChildren:Boolean;
+		
+		/**
+		 *  @private
+		 */ 
+		private var overlayControlsInvalidated:Boolean = false;
+		
+		/**
+		 *  @private
+		 *  The view data for the pending view.
+		 */ 
+		private var pendingViewDescriptor:org.apache.spark.components.supportClasses.ViewDescriptor = null;
+		
+		/**
+		 *  @private
+		 *  The transition to play when the pending view is activated.
+		 */ 
+		private var pendingViewTransition:org.apache.spark.transitions.ViewTransitionBase = null;
+		
+		/**
+		 *  @private
+		 *  A variable used to store the transition to play after a
+		 *  validation pass.  This needs to be a different variable than
+		 *  pendingViewTransition because the pending transition can
+		 *  change as push and pops come in.
+		 */
+		mx_internal var activeTransition:org.apache.spark.transitions.ViewTransitionBase;
+		
+		/**
+		 *  @private
+		 */
+		private var showingActionBar:Boolean;
+		
+		/**
+		 *  @private
+		 *  Flag indicates whether the navigator is in the process of
+		 *  changing a view.
+		 */ 
+		// mx_internal so that TabbedViewNavigator can access
+		mx_internal var viewChanging:Boolean = false;
+		
+		//--------------------------------------------------------------------------
+		//
+		//  Properties
+		// 
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  active
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  Only gets called by TabbedViewNavigator.
+		 */ 
+		override mx_internal function setActive(value:Boolean, clearNavigationStack:Boolean = false):void
+		{
+			if (value == isActive)
+				return;
+			
+			if (clearNavigationStack)
+				navigationStack.popToFirstView();
+			
+			if (value)
+			{
+				createTopView();
+				
+				// If the view is already initialized, that means it was cached.  We can complete the
+				// activation process if the view hasn't been invalidated in any way.
+				if (activeView)
+				{
+					const uiView:UIComponent = activeView as UIComponent;
+					if ( !uiView || 
+						( uiView.initialized && 
+						!uiView.invalidatePropertiesFlag && 
+						!uiView.invalidateSizeFlag && 
+						!uiView.invalidateDisplayListFlag))
+					{
+						completeViewCommitProcess();
+					}
+					else
+					{
+						// Wait until the view validates before activating it
+						activeView.addEventListener(FlexEvent.UPDATE_COMPLETE, view_updateCompleteHandler);
+					}
+				}
+				
+				// Need to force a validation on the actionBar
+				invalidateActionBarProperties();
+			}
+			else
+			{
+				if (activeView)
+				{
+					var canDestroy:Boolean = (activeView.destructionPolicy != ContainerDestructionPolicy.NEVER);
+					
+					// If the instance of the view is being destroyed but our navigationStack is
+					// maintained, the active view needs to serialize its data is application
+					// persistence is enabled.
+					if (canDestroy || clearNavigationStack)
+						destroyViewInstance(navigationStack.topView, !clearNavigationStack);
+					else
+						deactiveView(activeView);
+				}
+			}
+			
+			// Call super after the above code so that the view has a chance
+			// to be created before its active property is set.
+			super.setActive(value, clearNavigationStack);
+		}
+		
+		//----------------------------------
+		//  activeView
+		//----------------------------------
+		
+		[Bindable("viewChangeComplete")]
+		/**
+		 *  <p>During a view transition, this property references the
+		 *  view that the navigator is transitioning to.</p>
+		 *
+		 *  @inheritDoc
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		override public function get activeView():IView
+		{
+			if (pendingViewDescriptor)
+				return pendingViewDescriptor.instance;
+			
+			if (currentViewDescriptor && currentViewDescriptor != emptyViewDescriptor)
+				return currentViewDescriptor.instance;
+			
+			return null;
+		}
+		
+		//----------------------------------
+		//  exitApplicationOnBackKey
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 *  This method is used to determine whether the application can
+		 *  return to the home screen on Android when the back key is
+		 *  pressed.  An application can return to the home screen if the
+		 *  length of the navigator is 1 or less.
+		 */  
+		override mx_internal function get exitApplicationOnBackKey():Boolean
+		{
+			// If a back key is already being processed, we know that this
+			// method is being called as a result of a duplicate back key press
+			// during the same validation pass.  So don't return to the home screen
+			// and let the navigator process the navigation action during the
+			// next validation.
+			return !backKeyWasPressed && length <= 1;
+		}
+		
+		//----------------------------------
+		//  context
+		//----------------------------------
+		
+		/**
+		 *  The string that describes the context in which the current view was
+		 *  created.  
+		 *  This property is assigned to the value of the <code>context</code>
+		 *  parameter passed to the <code>ViewNavigator.pushView()</code> method.
+		 * 
+		 *  @default null
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get context():Object
+		{
+			if (pendingViewDescriptor)
+				return pendingViewDescriptor.context;
+			else if (currentViewDescriptor)
+				return currentViewDescriptor.context;
+			
+			return null;
+		}
+		
+		//---------------------------------
+		// defaultPushTransition
+		//---------------------------------
+		
+		private var _defaultPushTransition:org.apache.spark.transitions.ViewTransitionBase;
+		
+		
+		/**
+		 *  Specifies the default view transition for push navigation operations.
+		 *
+		 *  @default SlideViewTransition
+		 *
+		 *  @see spark.transitions.SlideViewTransition
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get defaultPushTransition():org.apache.spark.transitions.ViewTransitionBase
+		{
+			return _defaultPushTransition;
+		}
+		
+		/**
+		 * @private
+		 */
+		public function set defaultPushTransition(value:org.apache.spark.transitions.ViewTransitionBase):void
+		{
+			_defaultPushTransition = value;
+		}
+		
+		//---------------------------------
+		// defaultPopTransition
+		//---------------------------------
+		
+		private var _defaultPopTransition:org.apache.spark.transitions.ViewTransitionBase;
+		
+		/**
+		 *  Specifies the default view transition for pop navigation operations.
+		 *
+		 *  @default SlideViewTransition
+		 *
+		 *  @see spark.transitions.SlideViewTransition
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get defaultPopTransition():org.apache.spark.transitions.ViewTransitionBase
+		{
+			return _defaultPopTransition;
+		}
+		
+		/**
+		 * @private
+		 */
+		public function set defaultPopTransition(value:org.apache.spark.transitions.ViewTransitionBase):void
+		{
+			_defaultPopTransition = value;
+		}
+		
+		
+		//----------------------------------
+		//  firstView
+		//----------------------------------
+		
+		private var _firstView:Class;
+		
+		/**
+		 *  Each view in an application corresponds to a IView container 
+		 *  class defined in an ActionScript or MXML file.
+		 *  This property specifies the view to use to initialize the first view
+		 *  of the stack.  
+		 *  This property must reference a class that extends IView container.
+		 *
+		 *  <p>Specify any data passed to the first view by using 
+		 *  the <code>firstViewData</code> property.</p>   
+		 * 
+		 *  @default null
+		 *
+		 *  @see #firstViewData
+		 *  @see IView
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get firstView():Class
+		{
+			return _firstView;
+		}
+		
+		/**
+		 * @private
+		 */
+		public function set firstView(value:Class):void
+		{
+			_firstView = value;
+		}
+		
+		//----------------------------------
+		//  firstViewData
+		//----------------------------------
+		
+		private var _firstViewData:Object;
+		
+		/**
+		 *  The Object to pass to the <code>data</code> property 
+		 *  of the first view when the navigator is initialized.
+		 *  Specify the first view by using the <code>firstView</code> property.   
+		 * 
+		 *  @default null
+		 *
+		 *  @see #firstView
+		 *  @see IView
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get firstViewData():Object
+		{
+			return _firstViewData;
+		}
+		/**
+		 * @private
+		 */
+		public function set firstViewData(value:Object):void
+		{
+			_firstViewData = value;
+		}
+		
+		//----------------------------------
+		//  length
+		//----------------------------------
+		
+		[Bindable("lengthChanged")]
+		/**
+		 *  Returns the number of views being managed by the navigator.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get length():int
+		{
+			return navigationStack.length;
+		}
+		
+		//----------------------------------
+		//  navigationStack
+		//----------------------------------
+		
+		/**
+		 *  @private
+		 */
+		override mx_internal function set navigationStack(value:org.apache.spark.components.supportClasses.NavigationStack):void
+		{
+			super.navigationStack = value;
+			
+			viewChangeRequested = true;
+			invalidateProperties();
+		}
+		
+		//----------------------------------
+		//  poppedViewReturnedObject
+		//----------------------------------
+		private var _poppedViewReturnedObject:ViewReturnObject = null;
+		
+		/**
+		 *  Holds the object returned by the last view that was popped
+		 *  off the navigation stack or replaced by another view.  
+		 *  To return a value, the view being popped off the stack overrides
+		 *  its <code>createReturnObject()</code> method.
+		 *
+		 *  <p>This object is only available when the navigator is in the process of switching 
+		 *  views in response to a pop or replace navigation operation.  
+		 *  This object is guaranteed to be valid when the new view receives 
+		 *  the <code>add</code> event, and is destroyed after
+		 *  the view receives a <code>viewActivate</code> event.</p>
+		 * 
+		 *  @default null
+		 *
+		 *  @see IView#createReturnObject()
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */ 
+		public function get poppedViewReturnedObject():ViewReturnObject
+		{
+			return _poppedViewReturnedObject;
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		//  UI Template Properties
+		//
+		//--------------------------------------------------------------------------
+		
+		//----------------------------------
+		//  actionContent
+		//----------------------------------
+		
+		private var _actionContent:Array;
+		private var actionContentInvalidated:Boolean = false;
+		
+		[ArrayElementType("mx.core.IVisualElement")]
+		/**
+		 *  This property overrides the <code>actionContent</code>
+		 *  property in the ActionBar and 
+		 *  ViewNavigatorApplication components.
+		 * 
+		 *  @copy ActionBar#actionContent
+		 *
+		 *  @default null
+		 *
+		 *  @see ActionBar#actionContent
+		 *  @see spark.skins.mobile.ActionBarSkin
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get actionContent():Array
+		{
+			return _actionContent;
+		}
+		/**
+		 *  @private
+		 */
+		public function set actionContent(value:Array):void
+		{
+			_actionContent = value;
+			
+			if (!activeView || (activeView && !activeView.actionContent))
+			{
+				actionContentInvalidated = true;
+				invalidateProperties();
+			}
+		}
+		
+		//----------------------------------
+		//  actionLayout
+		//----------------------------------
+		
+		private var _actionLayout:LayoutBase;
+		private var actionLayoutInvalidated:Boolean = false;
+		
+		/**
+		 *  @copy ActionBar#actionContent
+		 *
+		 *  @default null
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get actionLayout():LayoutBase
+		{
+			return _actionLayout;
+		}
+		/**
+		 *  @private
+		 */
+		public function set actionLayout(value:LayoutBase):void
+		{
+			_actionLayout = value;
+			
+			if (!activeView || (activeView && !activeView.actionLayout))
+			{
+				actionLayoutInvalidated = true;
+				invalidateProperties();
+			}
+		}
+		
+		//----------------------------------
+		//  navigationContent
+		//----------------------------------
+		
+		private var _navigationContent:Array;
+		private var navigationContentInvalidated:Boolean = false;
+		
+		[ArrayElementType("mx.core.IVisualElement")]
+		/**
+		 *  This property overrides the <code>navigationContent</code>
+		 *  property in the ActionBar and 
+		 *  ViewNavigatorApplication components.
+		 * 
+		 *  @copy ActionBar#navigationContent
+		 *
+		 *  @default null
+		 * 
+		 *  @see ActionBar#navigationContent
+		 *  @see spark.skins.mobile.ActionBarSkin
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get navigationContent():Array
+		{
+			return _navigationContent;
+		}
+		/**
+		 *  @private
+		 */
+		public function set navigationContent(value:Array):void
+		{
+			_navigationContent = value;
+			
+			if (!activeView || (activeView && !activeView.navigationContent))
+			{
+				navigationContentInvalidated = true;
+				invalidateProperties();
+			}
+		}
+		
+		//----------------------------------
+		//  navigationLayout
+		//----------------------------------
+		
+		private var _navigationLayout:LayoutBase;
+		private var navigationLayoutInvalidated:Boolean = false;
+		
+		/**
+		 *  @copy ActionBar#navigationLayout
+		 *
+		 *  @default null
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get navigationLayout():LayoutBase
+		{
+			return _navigationLayout;
+		}
+		/**
+		 *  @private
+		 */
+		public function set navigationLayout(value:LayoutBase):void
+		{
+			_navigationLayout = value;
+			
+			if (!activeView || (activeView && !activeView.navigationLayout))
+			{            
+				navigationLayoutInvalidated = true;
+				invalidateProperties();
+			}
+		}
+		
+		//----------------------------------
+		//  title
+		//----------------------------------
+		
+		private var _title:String;
+		private var titleInvalidated:Boolean = false;
+		
+		[Bindable]
+		
+		/**
+		 *  This property overrides the <code>title</code>
+		 *  property in the ActionBar and ViewNavigatorApplication components.
+		 * 
+		 *  @copy ActionBar#title
+		 *
+		 *  @default ""
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */ 
+		public function get title():String
+		{
+			return _title;
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		public function set title(value:String):void
+		{
+			if (_title != value)
+			{
+				_title = value;
+				
+				// title will only have an effect on the view if titleContent or title isn't
+				// set anywhere else
+				if (!activeView || (activeView && !activeView.title && !activeView.titleContent && !titleContent))
+				{
+					titleInvalidated = true;
+					invalidateProperties();
+				}
+			}
+		}
+		
+		//----------------------------------
+		//  titleContent
+		//----------------------------------
+		
+		private var _titleContent:Array;
+		private var titleContentInvalidated:Boolean = false;
+		
+		[ArrayElementType("mx.core.IVisualElement")]
+		/**
+		 *  This property overrides the <code>titleContent</code>
+		 *  property in the ActionBar and ViewNavigatorApplication components.
+		 * 
+		 *  @copy ActionBar#titleContent
+		 *
+		 *  @default null
+		 * 
+		 *  @see ActionBar#titleContent
+		 *  @see spark.skins.mobile.ActionBarSkin
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get titleContent():Array
+		{
+			return _titleContent;
+		}
+		/**
+		 *  @private
+		 */
+		public function set titleContent(value:Array):void
+		{
+			_titleContent = value;
+			
+			if (!activeView || (activeView && !activeView.titleContent))
+			{
+				titleContentInvalidated = true;
+				invalidateProperties();
+			}
+		}
+		
+		//----------------------------------
+		//  titleLayout
+		//----------------------------------
+		
+		private var _titleLayout:LayoutBase;
+		private var titleLayoutInvalidated:Boolean = false;
+		
+		/**
+		 *  @copy ActionBar#titleLayout
+		 *
+		 *  @default null
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function get titleLayout():LayoutBase
+		{
+			return _titleLayout;
+		}
+		/**
+		 *  @private
+		 */
+		public function set titleLayout(value:LayoutBase):void
+		{
+			_titleLayout = value;
+			
+			if (!activeView || (activeView && !activeView.titleLayout))
+			{
+				titleLayoutInvalidated = true;
+				invalidateProperties();
+			}
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		// Public Methods
+		// 
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  Removes all of the views from the navigator stack.  
+		 *  This method changes the display to a blank screen.  
+		 *
+		 *  @param transition The view transition to play while switching views.    
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function popAll(transition:ViewTransitionBase = null):void
+		{
+			if (navigationStack.length == 0 || !canRemoveCurrentView())
+				return;
+			
+			scheduleAction(ViewNavigatorAction.POP_ALL, null, null, null, transition);
+		}
+		
+		/**
+		 *  Pops the current view off the navigation stack.
+		 *  The current view is represented by the top view on the stack.
+		 *  The previous view on the stack becomes the current view.
+		 * 
+		 *  @param transition The view transition to play while switching views.    
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */    
+		public function popView(transition:ViewTransitionBase = null):void
+		{
+			if (navigationStack.length == 0 || !canRemoveCurrentView())
+				return;
+			
+			scheduleAction(ViewNavigatorAction.POP, null, null, null, transition);
+		}
+		
+		/**
+		 *  Removes all views except the bottom view from the navigation stack.
+		 *  The bottom view is the one that was first pushed onto the stack.
+		 *  
+		 *  @param transition The view transition to play while switching views.    
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function popToFirstView(transition:ViewTransitionBase = null):void
+		{
+			if (navigationStack.length < 2 || !canRemoveCurrentView())
+				return;
+			
+			scheduleAction(ViewNavigatorAction.POP_TO_FIRST, null, null, null, transition);
+		}
+		
+		/**
+		 *  Pushes a new view onto the top of the navigation stack.
+		 *  The view pushed onto the stack becomes the current view. 
+		 * 
+		 *  @param viewClass The class used to create the view.
+		 *  This argument must reference a class that extends IView container.
+		 *  
+		 *  @param data The data object to pass to the view. 
+		 *  This argument is written to the <code>data</code> property of the new view.
+		 *  
+		 *  @param context An arbitrary object written to 
+		 *  the <code>ViewNavigator.context</code> property. 
+		 *  When the new view is created, it can reference this property 
+		 *  and perform an action based on its value. 
+		 *  For example, the view could display data in different ways based 
+		 *  on the value of <code>context</code>.
+		 *  
+		 *  @param transition The view transition to play while switching views.    
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function pushView(viewClass:Class, 
+								 data:Object = null,
+								 context:Object = null,
+								 transition:ViewTransitionBase = null):void
+		{
+			if (viewClass == null || !canRemoveCurrentView())
+				return;
+			
+			scheduleAction(ViewNavigatorAction.PUSH, viewClass, data, context, transition);
+		}
+		
+		/**
+		 *  Replaces the top view of the navigation stack with a new view.
+		 *  The view replacing the current view on the stack becomes the current view. 
+		 * 
+		 *  @param viewClass The class used to create the replacement view.
+		 *  This argument must reference a class that extends IView container.
+		 *  
+		 *  @param data The data object to pass to the view. 
+		 *  This argument is written to the <code>data</code> property of the new view.
+		 *  
+		 *  @param context An arbitrary object used to describe the context
+		 *         of the push.  When the new view is created, it can
+		 *         reference this property.
+		 *  
+		 *  @param transition The view transition to play while switching views.    
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function replaceView(viewClass:Class,
+									data:Object = null,
+									context:Object = null,
+									transition:ViewTransitionBase = null):void
+		{
+			if (viewClass == null || !canRemoveCurrentView())
+				return;
+			
+			scheduleAction(ViewNavigatorAction.REPLACE, viewClass, data, context, transition);
+		}
+		
+		/**
+		 *  Shows the action bar.
+		 * 
+		 *  @param animate Indicates whether a show effect should be played
+		 *  when the action bar appears.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function showActionBar(animate:Boolean = true):void
+		{
+			if (!actionBar)
+				return;
+			
+			// Ignore this call if the actionBar is already being shown
+			if (actionBarVisibilityEffect && showingActionBar)
+				return;
+			
+			showingActionBar = true;
+			animateActionBarVisbility = animate;
+			actionBarVisibilityInvalidated = true;
+			
+			invalidateProperties();
+		}
+		
+		/**
+		 *  Hides the action bar.
+		 * 
+		 *  @param animate Indicates whether a hide effect should be played
+		 *  when the action bar is hidden.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		public function hideActionBar(animate:Boolean = true):void
+		{   
+			if (!actionBar)
+				return;
+			
+			// Ignore this call if the actionBar is already being hidden
+			if (actionBarVisibilityEffect && !showingActionBar)
+				return;
+			
+			showingActionBar = false;
+			animateActionBarVisbility = animate;
+			actionBarVisibilityInvalidated = true;
+			
+			invalidateProperties();
+		}
+		
+		/**
+		 *  Pops to the previous view of the navigator in response to the back
+		 *  key.  ViewNavigator only allows this method to be called once during
+		 *  a navigation event.  All subsequent calls to this method will be ignored
+		 *  until the current view transition is complete.
+		 * 
+		 *  <p>ViewNavigatorApplication automatically calls this method when the back
+		 *  key is pressed.</p>
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 3.1
+		 *  @productversion Flex 4.6
+		 */
+		override public function backKeyUpHandler():void
+		{
+			if (!backKeyWasPressed && activeView && !activeView.backKeyHandledByView())
+			{
+				popView();
+				backKeyWasPressed = true;
+			}
+		}
+		
+		//--------------------------------------------------------------------------
+		//
+		// Protected Methods
+		// 
+		//--------------------------------------------------------------------------
+		
+		/**
+		 *  @private
+		 *  Initializes the view change process by disabling inputs on the
+		 *  navigator.  If the navigator has a parent, the parents mouse
+		 *  interaction flags are disabled.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		protected function committingNavigatorAction():void
+		{
+			viewChanging = true;
+			
+			explicitMouseChildren = mouseChildren;
+			explicitMouseEnabled = mouseEnabled;
+			mouseEnabled = false;
+			mouseChildren = false;
+		}
+		
+		/**
+		 *  @private
+		 */
+		override mx_internal function canRemoveCurrentView():Boolean
+		{
+			var view:IView;
+			
+			if (!currentViewDescriptor)
+				return true;
+			
+			view = currentViewDescriptor.instance;
+			return (view == null || view.canRemove());
+		}
+		
+		/**
+		 *  @private
+		 *  Helper method that clears the action bar property invalidation flags.
+		 * 
+		 *  @default null
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		private function clearActionBarInvalidationFlags():void
+		{
+			actionContentInvalidated = false;
+			actionLayoutInvalidated = false;
+			navigationContentInvalidated = false;
+			navigationLayoutInvalidated = false;
+			titleInvalidated = false;
+			titleContentInvalidated = false;
+			titleLayoutInvalidated = false;
+			overlayControlsInvalidated = false;
+		}
+		
+		/**
+		 *  @private
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */ 
+		override protected function commitProperties():void
+		{
+			if (!isActive)
+				return;
+			
+			// If this is the components first validation pass, push the firstView
+			// on the stack if possible, otherwise set the currentViewChange flag
+			// to true so that an empty screen is created.  If the currentViewDescriptor
+			// property exists, that means an empty view was previously created 
+			// because a firstView property wasn't supplied.
+			if (!initialized && navigationStack.length == 0 && !currentViewDescriptor)
+			{
+				if (firstView)
+					navigationStack.pushView(firstView, firstViewData);
+				
+				viewChangeRequested = true;
+			}
+			
+			if (viewChangeRequested)
+				commitNavigatorAction();
+			
+			// Updating the action bar properties and visibility is the responsibility
+			// of commitViewChange if the current view has changed because they must take
+			// part in transitions. If the view change is processed during this validation,
+			// the following flags will be false.
+			if (actionBarPropertyInvalidated)
+				updateControlsForView(activeView);
+			
+			if (actionBarVisibilityInvalidated)
+				commitVisibilityChanges();
+			
+			// When true, this flag prevents action bar animations from running.  This flag 
+			// is only set to  true if the application received an orientation event this 
+			// frame (See ViewNavigatorBase).  The flag is reset at the end of commitProperties 
+			// so that animations run again.
+			if (disableNextControlAnimation)
+				disableNextControlAnimation = false;
+			
+			// Call base class' commitProperties after the above so that state changes
+			// as a result of overlayControls are caught.  This is okay because
+			// this method doesn't rely on any properties from the base class.
+			super.commitProperties();
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		private function get lastActionWasAPop():Boolean
+		{
+			return ((lastAction == ViewNavigatorAction.POP) ||
+				(lastAction == ViewNavigatorAction.POP_ALL) ||
+				(lastAction == ViewNavigatorAction.POP_TO_FIRST) ||
+				(lastAction == ViewNavigatorAction.REPLACE));
+		}
+		
+		/**
+		 *  @private
+		 *  This method registers a navigation operation with the navigators
+		 *  action queue.  Navigation operations aren't performed until the
+		 *  following frame to allow components to properly update their
+		 *  visual state before any complicated actionScript code is run by the
+		 *  navigator.
+		 * 
+		 *  <p>This method will execute all operations when the next ENTER_FRAME
+		 *  event is dispatched by the runtime.</P.
+		 * 
+		 *  @param action The navigation operation that is being performed.  Should
+		 *  be one of the constants in ViewNavigatorAction.
+		 *  @param viewClass The class that will be created in the case of a push action
+		 *  @param data The data object to pass to the view in the case of a push action
+		 *  @param transition The view transition to play
+		 *  @param context An arbitrary string that can be used to describe the context
+		 *         of the push.  When the new view is created, it will be able to reference
+		 *         this property.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */  
+		private function scheduleAction(action:String, 
+										viewClass:Class = null, 
+										data:Object = null, 
+										context:Object = null,
+										transition:ViewTransitionBase = null):void
+		{
+			// ViewNavigator does not allow a push or replace operation to occur
+			// without the viewClass factory object defined.
+			if (action == ViewNavigatorAction.PUSH || action == ViewNavigatorAction.REPLACE)
+			{
+				if (!viewClass)
+					return;
+			}
+			
+			// Navigation operations are not committed immediately to allow the UI
+			// to update before beginning the creation process.  When an action is
+			// queued for the first time, we add an enter frame listener.
+			if (delayedNavigationActions.length == 0)
+			{
+				// If the navigator is currently in the process of switching views,
+				// the queued actions will automatically be run later in
+				// navigatorActionCommitted() when the transition is complete.
+				// So there is no need to add the ENTER_FRAME listener.
+				if (!viewChanging)
+					addEventListener(Event.ENTER_FRAME, executeDelayedActions);
+			}
+			
+			delayedNavigationActions.push({action:action, viewClass:viewClass, 
+				data:data, transition:transition, context:context});
+			
+			if (activeView)
+				activeView.dispatchEvent(new Event("_navigationChange_"));
+		}
+		
+		/**
+		 *  @private
+		 *  Executes all the navigation operations that have been queued
+		 *  by the navigation methods (e.g., popView, pushView).
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */  
+		private function executeDelayedActions(event:Event = null):void
+		{
+			if (event)
+				removeEventListener(Event.ENTER_FRAME, executeDelayedActions);
+			
+			if (delayedNavigationActions.length == 0)
+				return;
+			
+			var parameters:Object;
+			var n:int = delayedNavigationActions.length;
+			for (var i:int = 0; i < n; ++i)
+			{
+				parameters = delayedNavigationActions[i];
+				executeAction(parameters.action, parameters.viewClass, 
+					parameters.data, parameters.context, parameters.transition); 
+			}
+			
+			delayedNavigationActions.length = 0;
+			
+			viewChangeRequested = true;
+			invalidateProperties();
+		}
+		
+		/**
+		 *  @private
+		 *  Helper method that executes navigation operations for the navigator.
+		 * 
+		 *  @param action The navigation operation that is being performed.  Should
+		 *  be one of the constants in ViewNavigatorAction.
+		 *  @param viewClass The class that will be created in the case of a push action
+		 *  @param data The data object to pass to the view in the case of a push action
+		 *  @param transition The view transition to play
+		 *  @param context An arbitrary string that can be used to describe the context
+		 *         of the push.  When the new view is created, it will be able to reference
+		 *         this property.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */    
+		private function executeAction(action:String, viewClass:Class = null, 
+									   data:Object = null,
+									   context:Object = null,
+									   transition:org.apache.spark.transitions.ViewTransitionBase = null):void
+		{
+			var defaultTransition:org.apache.spark.transitions.ViewTransitionBase;
+			
+			lastAction = action;
+			
+			// Perform the correct operation on the navigation stack based on
+			// the navigation action
+			if (action == ViewNavigatorAction.PUSH)
+			{
+				defaultTransition = defaultPushTransition;
+				navigationStack.pushView(viewClass, data, context);
+			}
+			else if (action == ViewNavigatorAction.REPLACE)
+			{
+				defaultTransition = defaultPushTransition;
+				navigationStack.popView();
+				navigationStack.pushView(viewClass, data, context);
+			}
+			else
+			{
+				defaultTransition = defaultPopTransition;
+				
+				if (action == ViewNavigatorAction.POP)
+				{
+					navigationStack.popView();
+				}
+				else if (action == ViewNavigatorAction.POP_TO_FIRST)
+				{
+					navigationStack.popToFirstView();
+				}
+				else if (action == ViewNavigatorAction.POP_ALL)
+				{
+					navigationStack.clear();
+				}
+			}
+			
+			pendingViewTransition = transition;
+			if (pendingViewTransition == null)
+				pendingViewTransition = defaultTransition;
+		}
+		
+		/**
+		 *  @private
+		 *  Invalidates all action bar property flags.
+		 */
+		private function invalidateActionBarProperties():void
+		{
+			actionContentInvalidated = true;
+			actionLayoutInvalidated = true;
+			navigationContentInvalidated = true;
+			navigationLayoutInvalidated = true;
+			titleInvalidated = true;
+			titleContentInvalidated = true;
+			overlayControlsInvalidated = true;
+			titleLayoutInvalidated = true;
+			
+			invalidateProperties();
+		}
+		
+		/**
+		 *  @private
+		 *  Commits the visiblity changes that have been requested.  This method
+		 *  is called during an invalidation pass if the current view has not changed
+		 *  and the action bar's visibility has changed.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		private function commitVisibilityChanges():void
+		{
+			if (viewChanging)
+			{
+				actionBarVisibilityInvalidated = false;
+				return;
+			}
+			
+			// If an animation is running, end it
+			if (actionBarVisibilityEffect)
+				actionBarVisibilityEffect.end();
+			
+			if (actionBar && showingActionBar != actionBar.visible)
+			{
+				if (!disableNextControlAnimation && transitionsEnabled && animateActionBarVisbility)
+				{
+					actionBarProps = {target:actionBar, showing:showingActionBar};
+					actionBarVisibilityEffect = showingActionBar ?
+						createActionBarShowEffect() :                        
+						createActionBarHideEffect();
+					
+					actionBarVisibilityEffect.addEventListener(EffectEvent.EFFECT_END, 
+						visibilityAnimation_effectEndHandler);
+					
+					actionBarVisibilityEffect.play();
+				}
+				else
+				{
+					actionBar.visible = actionBar.includeInLayout = showingActionBar;
+					
+					if (activeView)
+						activeView.setActionBarVisible(showingActionBar);
+				}
+			}
+			
+			actionBarVisibilityInvalidated = false;
+		}
+		
+		/**
+		 *  Creates the effect to play when the ActionBar control is hidden.
+		 *  The produced effect is responsible for animating both the 
+		 *  ActionBar and the view currently displayed in the 
+		 *  content area of the navigator.
+		 * 
+		 *  @return An effect to play when the ActionBar control is hidden.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		protected function createActionBarHideEffect():IEffect
+		{
+			return createActionBarVisibilityEffect(false);
+		}
+		
+		
+		/**
+		 *  Creates the effect to play when the ActionBar control appears.
+		 *  The produced effect is responsible for animating both the 
+		 *  ActionBar and the view currently displayed in the 
+		 *  content area of the navigator.
+		 * 
+		 *  @return An effect to play when the ActionBar control is appears.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		protected function createActionBarShowEffect():IEffect
+		{
+			return createActionBarVisibilityEffect(true);
+		}
+		
+		/**
+		 *  @private
+		 */   
+		private function createActionBarVisibilityEffect(showAnimation:Boolean):IEffect
+		{
+			var effect:IEffect;
+			var finalEffect:Parallel = new Parallel();
+			
+			// Grab initial values
+			actionBarProps.start = captureAnimationValues(actionBar);
+			contentGroupProps = { target:contentGroup, start:captureAnimationValues(contentGroup) };
+			
+			// Update actionBar layout properties so we can capture the final state of
+			// of the navigator
+			actionBar.visible = actionBar.includeInLayout = showAnimation;
+			
+			// Calculate final positions and position actionBar.  This method will force a validation
+			prepareActionBarForAnimation(showAnimation);
+			
+			// Create animation for action bar 
+			var animate:Animate = new Animate();
+			animate.target = actionBar;
+			animate.duration = ACTION_BAR_ANIMATION_DURATION;
+			animate.motionPaths = new Vector.<MotionPath>();
+			animate.motionPaths.push(new SimpleMotionPath("y", actionBarProps.start.y, actionBarProps.end.y));
+			
+			// Add action bar effect to final parallel effect
+			effect = animate;        
+			finalEffect.addChild(effect);
+			
+			// Create animation for content group
+			effect = createContentVisibilityEffect(contentGroupProps);
+			effect.target = contentGroup;
+			finalEffect.addChild(effect);
+			
+			return finalEffect;
+		}
+		
+		/**
+		 *  @private
+		 *  Responsible for calculating the final positions of the action bar
+		 *  when it's visiblity is changed.  This method will force a validation
+		 *  pass.
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		private function prepareActionBarForAnimation(showAnimation:Boolean):void
+		{
+			var animateActionBarUp:Boolean;
+			
+			// Determine whether the action bar should be animated up or down
+			if (overlayControls)
+			{
+				// If the control is overlaid on top, the actionBar is animated up if 
+				// the actionBar is above the center of the navigator
+				animateActionBarUp = (actionBar.y + (actionBar.height / 2)) <= height / 2;
+			}
+			else
+			{
+				// The actionBar is animated up if it is above the contentGroup
+				animateActionBarUp = actionBar.y <= contentGroup.y;
+			}
+			
+			// Need to validate to capture final positions and sizes of skin parts.
+			// If the navigator is a child of another, we need the root navigator
+			// to perform the validation so that all widths and heights of all
+			// containers are sized.
+			LayoutManager.getInstance().validateNow();
+			
+			// This will store the final location and sizes of the components
+			actionBarProps.end = captureAnimationValues(actionBar);
+			contentGroupProps.end = captureAnimationValues(contentGroup);
+			
+			// Update the end position of the animation based on whether the
+			// actionBar is showing/hiding and if it is animating up or down.
+			if (animateActionBarUp)
+			{
+				if (showAnimation)
+					actionBarProps.start.y = -actionBar.height;
+				else
+					actionBarProps.end.y = -actionBar.height;
+			}
+			else
+			{
+				if (showAnimation)
+					actionBarProps.start.y = this.height;
+				else
+					actionBarProps.end.y = this.height;
+			}
+			
+			actionBar.visible = true;
+			actionBar.includeInLayout = false;
+			actionBar.cacheAsBitmap = true;
+		}
+		
+		/**
+		 *  @private
+		 *  Creates the effect to play on the contentGroup when the navigator is
+		 *  generating an animation to play to hide or show the action bar.  This effect
+		 *  should only target the contentGroup as it will be played in parallel with
+		 *  other effects that animate the other navigator skin parts.
+		 * 
+		 *  @param hiding Indicates whether the action bar is hiding or showing
+		 *  @param props The bounds properties that were captured for the actionBar.  
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		private function createContentVisibilityEffect(props:Object):IEffect
+		{
+			var animate:Animate = new Animate();
+			animate.target = contentGroup;
+			animate.duration = ACTION_BAR_ANIMATION_DURATION;
+			animate.motionPaths = new Vector.<MotionPath>();
+			animate.motionPaths.push(new SimpleMotionPath("height", props.start.height, props.end.height));
+			animate.motionPaths.push(new SimpleMotionPath("y", props.start.y, props.end.y));
+			
+			contentGroup.includeInLayout = false;
+			return animate;
+		}
+		
+		/**
+		 *  @private
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		private function visibilityAnimation_effectEndHandler(event:EffectEvent):void
+		{
+			event.target.removeEventListener(EffectEvent.EFFECT_END, visibilityAnimation_effectEndHandler);
+			
+			// Clear flags and temporary properties
+			actionBarVisibilityEffect = null;
+			
+			if (activeView)
+				activeView.setActionBarVisible(actionBarProps.showing);
+			
+			// Check if the visible and cacheAsBitmap properties have been set.  These are
+			// only set if the default transitions are used.  If developers create their
+			// own animations, these properties won't be set.
+			if (actionBarProps.start != undefined)
+			{
+				actionBar.visible = actionBar.includeInLayout = !actionBarProps.start.visible;
+				actionBar.cacheAsBitmap = actionBarProps.start.cacheAsBitmap;
+			}
+			
+			actionBarProps = null;
+			
+			// Content group properties object only created if the default transitions were used
+			if (contentGroupProps)
+			{
+				contentGroup.includeInLayout = contentGroupProps.start.includeInLayout;
+				
+				// The default action bar hide and show animation will animate the width and height
+				// of the navigator's contentGroup.  If the explicitWidth or explicitHeight properties
+				// were NaN before the animation, they'll be set to real values by the animation.  As
+				// a result, it is necessary to restore them to NaN so that layout properly sizes these
+				// components. 
+				if (isNaN(contentGroupProps.start.explicitHeight))
+					contentGroup.explicitHeight = NaN;
+				
+				if (isNaN(contentGroupProps.start.explicitWidth))
+					contentGroup.explicitWidth = NaN;
+				
+				if (!isNaN(contentGroupProps.start.percentWidth))
+					contentGroup.percentWidth = contentGroupProps.start.percentWidth;
+				
+				if (!isNaN(contentGroupProps.start.percentHeight))
+					contentGroup.percentHeight = contentGroupProps.start.percentHeight;
+				
+				contentGroupProps = null;
+			}
+		}
+		
+		/**
+		 *  @private
+		 *  This method is responsible for completing a view change validation pass.
+		 *  It is responsible for cleaning up and destroying the old view, as well as
+		 *  activating the new one.
+		 * 
+		 *  <p>If a transition was played, this method is called after the transition
+		 *  completes.</p>
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		protected function navigatorActionCommitted():void
+		{
+			// Destroy the previous view
+			if (currentViewDescriptor)
+				destroyViewInstance(currentViewDescriptor);
+			
+			// Update view pointers
+			currentViewDescriptor = pendingViewDescriptor;
+			pendingViewDescriptor = null;
+			
+			// Clear empty flag if necessary
+			if (emptyViewDescriptor && currentViewDescriptor != emptyViewDescriptor)
+				emptyViewDescriptor = null;
+			
+			// If there is no focus or the item that had focus isn't 
+			// on the display list anymore, update the focus to be
+			// the active view or the view navigator
+			updateFocus();
+			
+			// Clear the returned object
+			_poppedViewReturnedObject = null;
+			
+			// Restore mouse children properties before revalidation occurs.  This
+			// needs to occur before a possible revalidation occurs so that the
+			// saved mouseChildren and mouseEnabled flags aren't overwritten.
+			mouseChildren = explicitMouseChildren;
+			mouseEnabled = explicitMouseEnabled;
+			
+			// SDK-28230
+			// Wait a frame before sending the complete event so that the player 
+			// has the chance to render the last frame before any custom actionscript 
+			// is run in response to a VIEW_ACTIVATE event.
+			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
+		}
+		
+		/**
+		 *  @private
+		 *  Called when the activeView has received its first updateComplete event
+		 *  after the navigator has been activated.  See setActive().
+		 */ 
+		private function view_updateCompleteHandler(event:FlexEvent):void
+		{
+			event.target.removeEventListener(FlexEvent.UPDATE_COMPLETE, view_updateCompleteHandler);
+			completeViewCommitProcess();
+		}
+		
+		/**
+		 *  @private
+		 *  Called after a navigation operation is complete.  See 
+		 *  navigatorActionCommitted().
+		 */   
+		private function enterFrameHandler(event:Event):void
+		{
+			removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
+			completeViewCommitProcess();    
+		}
+		
+		/**
+		 *  @private
+		 *  Activates the current view and completes the view change process.
+		 */ 
+		private function completeViewCommitProcess():void
+		{
+			// ViewNavigator doesn't allow for another navigation operation to
+			// be run during a view change.  If the component attempts to do
+			// one, it is queued and run after the current transition is complete.
+			// The delayedNavigationActions queue size will be non zero in that case.
+			// If there are items in the queue, force another validation to commit
+			// navigation change.  Otherwise the transition process can end.
+			if (delayedNavigationActions.length > 0)
+			{
+				executeDelayedActions();
+				commitNavigatorAction();
+				return;
+			}
+			
+			// The viewChanging flag is set to false right before the current view 
+			// activates so that navigation operations run during VIEW_ACTIVATE
+			// are properly executed by the navigator 
+			viewChanging = false;
+			
+			// At this point, currentViewDescriptor points to the new view.
+			// The navigator needs to listen for property change events on the
+			// view so that it can be notified when the template properties
+			// (e.g, title, titleContent, etc) are changed.
+			if (currentViewDescriptor)
+			{
+				var currentView:IView = currentViewDescriptor.instance;
+				
+				if (currentView)
+				{
+					currentView.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, 
+						view_propertyChangeHandler);
+					
+					// Activate the current view.  This will dispatch a VIEW_ACTIVATE event.
+					currentView.setActive(true);
+				}
+			}
+			
+			// Notify listeners that the view change is complete
+			if (hasEventListener("viewChangeComplete"))
+				dispatchEvent(new Event("viewChangeComplete"));
+			
+			// Clear flag indicating that the back key was pressed
+			backKeyWasPressed = false;
+			lastAction = ViewNavigatorAction.NONE;
+		}
+		
+		/**
+		 *  @private
+		 *  Called in commitProperties() and begins the view transition
+		 *  process.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		protected function commitNavigatorAction():void
+		{
+			if (!isActive)
+			{
+				viewChangeRequested = false;
+				return;
+			}
+			
+			// Private event
+			if (hasEventListener("viewChangeStart"))
+				dispatchEvent(new Event("viewChangeStart"));
+			
+			// If a ui control is animating, force it to end
+			if (actionBarVisibilityEffect)
+				actionBarVisibilityEffect.end();
+			
+			if (activeView && lastActionWasAPop)
+			{
+				_poppedViewReturnedObject = createViewReturnObject(currentViewDescriptor);
+			}
+			
+			committingNavigatorAction();
+			
+			pendingViewDescriptor = navigationStack.topView;
+			
+			// Create an empty view if no firstView viewClass is defined
+			if (pendingViewDescriptor == null)
+			{
+				emptyViewDescriptor = new org.apache.spark.components.supportClasses.ViewDescriptor(ViewGroup);
+				pendingViewDescriptor = emptyViewDescriptor;
+			}
+			
+			if (pendingViewDescriptor.viewClass != null)
+			{
+				var view:IView = createViewInstance(pendingViewDescriptor);
+				
+				viewChangeRequested = false;
+				
+				// Hide the view so that it doesn't render this frame
+				view.setVisible( false );
+				
+				activeTransition = transitionsEnabled ? pendingViewTransition : null;
+				
+				// TODO (chiedozi): Consider capturingStartValues now and updating actionBar
+				// to remove forced validation in prepareViewTransition()
+				
+				// Prepare the view transition after the navigator has validated the new IView
+				addEventListener(FlexEvent.UPDATE_COMPLETE, prepareViewTransition);
+			}
+			
+			pendingViewTransition = null;
+		}
+		
+		/**
+		 *  @private
+		 *  This method is used to create the top view of the ViewNavigator.  This
+		 *  is only used by TabbedViewNavigator when the selected tab has changed.
+		 */ 
+		override mx_internal function createTopView():void
+		{
+			// Check if the top view already exists
+			if (activeView)
+				return;
+			
+			invalidateActionBarProperties();
+			
+			// If the navigation stack is empty, push on the firstView for the
+			// navigator.
+			if (navigationStack.length == 0)
+			{
+				if (firstView != null)
+					navigationStack.pushView(firstView, firstViewData);
+				else
+					return;
+			}
+			
+			// Update the current view reference
+			currentViewDescriptor = navigationStack.topView;
+			
+			// Create the view if needed
+			var view:IView = currentViewDescriptor.instance;
+			if (!view)
+			{
+				view = createViewInstance(currentViewDescriptor);
+				view.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, view_propertyChangeHandler);
+			}
+			
+			// Cancel any view change requests that occurred prior to this call
+			// since the top most view was just created.
+			viewChangeRequested = false;
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function createViewInstance(viewProxy:org.apache.spark.components.supportClasses.ViewDescriptor):IView
+		{
+			var view:IView;
+			
+			if (viewProxy.instance == null)
+			{
+				view = new viewProxy.viewClass();
+				viewProxy.instance = view;
+			}
+			else
+			{
+				view = viewProxy.instance;
+				
+				// Need to update the view's orientation state if it was saved
+				view.setCurrentState(view.getCurrentViewState(), false);
+			}
+			
+			// Restore persistence data if necessary
+			if (viewProxy.data == null && viewProxy.persistenceData != null)
+				viewProxy.data = view.deserializeData(viewProxy.persistenceData);
+			
+			view.setNavigator(this);
+			view.data = viewProxy.data;
+			// TODO
+			//view.percentWidth = view.percentHeight = 100;
+			
+			addElement(view);
+			
+			return view;
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		private function createViewReturnObject(viewProxy:org.apache.spark.components.supportClasses.ViewDescriptor):ViewReturnObject
+		{
+			var view:IView = viewProxy.instance;
+			
+			if (view)
+				return new ViewReturnObject(view.createReturnObject(), viewProxy.context);
+			
+			return null;
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		private function destroyViewInstance(viewProxy:org.apache.spark.components.supportClasses.ViewDescriptor, forceDataPersist:Boolean = false):void
+		{
+			var currentView:IView = viewProxy.instance;
+			
+			if (!currentView)
+				return;
+			
+			// Deactivate the view if it is active
+			deactiveView(currentView);
+			removeElement(currentView);
+			
+			// Grab the data from the old view and persist it
+			if (lastAction == ViewNavigatorAction.PUSH || forceDataPersist)
+			{
+				viewProxy.data = currentView.data;
+				viewProxy.persistenceData = currentView.serializeData();
+			}
+			
+			// Check if we can delete the reference for the view instance.  If the current
+			// view is being replaced or popped of the stack, we know we can delete it.
+			// Otherwise a push is happening and we need to check the destructionPolicy
+			// of the view.
+			if (lastActionWasAPop || currentView.destructionPolicy != ContainerDestructionPolicy.NEVER)
+			{
+				currentView.setNavigator(null);
+				viewProxy.instance = null;
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		private function deactiveView(view:IView):void
+		{
+			if (view.isActive)
+				view.setActive(false);
+			
+			view.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, 
+				view_propertyChangeHandler);
+		}
+		
+		/**
+		 *  @private
+		 */
+		override public function saveViewData():Object
+		{
+			var savedData:Object = super.saveViewData();
+			
+			if (currentViewDescriptor && currentViewDescriptor.instance)
+				currentViewDescriptor.persistenceData = currentViewDescriptor.instance.serializeData();
+			
+			if (!savedData)
+				savedData = {};
+			
+			savedData.navigationStack = navigationStack;
+			return savedData;
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		override public function loadViewData(value:Object):void
+		{
+			super.loadViewData(value);
+			
+			if (value)
+				navigationStack = value.navigationStack as org.apache.spark.components.supportClasses.NavigationStack; 
+		}
+		
+		/**
+		 *  @private
+		 *  Method is called during the view transition process after the
+		 *  instance of the new view is added to the display list.  It initializes
+		 *  the underlying ViewDescriptor object and prepares the transition.
+		 * 
+		 *  Called after the UPDATE_COMPLETE event is received on the navigator
+		 *  after the pendingView is added to the display list.  
+		 *  See commitNavigatorAction.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		private function prepareViewTransition(event:Event):void
+		{
+			removeEventListener(FlexEvent.UPDATE_COMPLETE, prepareViewTransition);
+			
+			var currentView:IView;
+			var pendingView:IView;
+			
+			// Deactivate the current view
+			if (currentViewDescriptor)
+			{
+				currentView = currentViewDescriptor.instance;
+				currentView.setActive(false);
+				
+				// In most cases this is a No-Op because this method is called in response
+				// to UPDATE_COMPLETE on the navigator and there should be no objects
+				// in the LayoutManager's queue.  It's only here to ensure that the
+				// current view is up to date incase anything changed.
+				currentView.validateNow();
+			}
+			
+			// Store new view
+			if (pendingViewDescriptor)
+			{
+				pendingView = pendingViewDescriptor.instance;
+				pendingView.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, 
+					view_propertyChangeHandler);
+			}
+			
+			if (activeTransition)
+			{
+				activeTransition.addEventListener(FlexEvent.TRANSITION_END, transitionComplete);
+				activeTransition.startView = currentView as UIComponent;
+				activeTransition.endView = pendingView as UIComponent;
+				activeTransition.navigator = this;
+				activeTransition.preInit();
+				
+				if (stage)
+					stage.dispatchEvent(new Event("viewTransitionPrepare"));
+			}
+			
+			// Only dispatch this event if the stage exists.
+			if (stage && viewTransitionSuspendCount > 0)
+			{
+				if (!eventDispatcher)
+					eventDispatcher = new EventDispatcher();
+				
+				eventDispatcher.addEventListener("viewTransitionReady", completeTransitionPreparations);
+			}
+			else
+			{
+				completeTransitionPreparations();
+			}
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		mx_internal static function suspendTransitions():void
+		{
+			viewTransitionSuspendCount++;   
+		}
+		
+		/**
+		 *  @private
+		 */
+		mx_internal static function resumeTransitions():void
+		{
+			if (viewTransitionSuspendCount == 0)
+				return;
+			
+			viewTransitionSuspendCount--;
+			
+			if (viewTransitionSuspendCount == 0)
+				eventDispatcher.dispatchEvent(new Event("viewTransitionReady"));
+		}
+		
+		/**
+		 *  @private
+		 */ 
+		private function completeTransitionPreparations(event:Event = null):void
+		{
+			if (event)
+				event.target.removeEventListener("viewTransitionReady", completeTransitionPreparations);
+			
+			var pendingView:IView;
+			if (pendingViewDescriptor)
+			{
+				pendingView = pendingViewDescriptor.instance;
+				pendingView.setVisible( true );
+			}
+			
+			// Give the transition a chance to prepare before the view updates
+			if (activeTransition)
+				activeTransition.captureStartValues();
+			
+			// This event is dispatched here to allow developers to incorporate
+			// length specific changes into the view navigator transitions
+			if (hasEventListener("lengthChanged"))
+				dispatchEvent(new Event("lengthChanged"));
+			
+			// Invalidate the actionBar properties
+			if (actionBar)
+			{
+				invalidateActionBarProperties();
+				updateControlsForView(pendingView);
+			}
+			
+			// Only force validation for the navigator if initialized to avoid
+			// validation from occurring with wrong measured dimensions
+			if (initialized)
+			{
+				// Need to validate my children now to prevent flicker when no transition,
+				// or so sizes can be measured before transition
+				if (parentNavigator)
+					UIComponent(parentNavigator).validateNow();
+				else
+					validateNow();
+			}
+			
+			if (activeTransition)
+			{
+				activeTransition.captureEndValues();
+				activeTransition.prepareForPlay();
+				
+				// Wait a frame so that any queued work can be completed by the framework
+				// and runtime before the transition starts.  As of Flex 4.6, we wait 2
+				// frames to allow StageText to fully render the swapped in bitmaps.  
+				// Otherwise rendering time would overlap with the first frame of the animation.
+				enterFrameCount = 0;
+				addEventListener(Event.ENTER_FRAME, startViewTransition);
+			}
+			else
+			{
+				navigatorActionCommitted();
+			}
+		}
+		
+		/**
+		 *  @private
+		 *  Starts the view transition.
+		 */
+		private function startViewTransition(event:Event):void
+		{
+			// Incrememnt the enterFrameCount.  ViewNavigator waits two frames
+			// before begining the animation.
+			enterFrameCount++;
+			if (enterFrameCount < 2)
+				return;
+			
+			// Remove the enter frame listener
+			removeEventListener(Event.ENTER_FRAME, startViewTransition);
+			
+			if (hasEventListener(FlexEvent.TRANSITION_START))
+				dispatchEvent(new FlexEvent(FlexEvent.TRANSITION_START, false, false));
+			
+			// Force the master clock of the animation engine to update its
+			// current time so that the overhead of creating the view and preparing
+			// the transition is not included in our animation interpolation.
+			// See SDK-27793
+			Animation.pulse();
+			activeTransition.play();
+		}
+		
+		/**
+		 *  @private
+		 *  Called when a transition dispatches an FlexEvent.TRANSITION_END event.
+		 * 
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		private function transitionComplete(event:Event):void
+		{
+			org.apache.spark.transitions.ViewTransitionBase(event.target).removeEventListener(FlexEvent.TRANSITION_END, transitionComplete);
+			
+			if (hasEventListener(FlexEvent.TRANSITION_END))
+				dispatchEvent(new FlexEvent(FlexEvent.TRANSITION_END, false, false));
+			
+			activeTransition = null;
+			navigatorActionCommitted();
+		}
+		
+		/**
+		 *  @private
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		override public function updateControlsForView(view:IView):void
+		{
+			super.updateControlsForView(view);
+			
+			if (!actionBar)
+				return;
+			
+			// If there is no view, update the actionBar should display the 
+			// navigator defaults
+			if (view == null)
+			{
+				actionBar.actionContent = actionContent;
+				actionBar.actionLayout = actionLayout;
+				actionBar.navigationContent = navigationContent;
+				actionBar.navigationLayout = navigationLayout;
+				actionBar.title = title;
+				actionBar.titleContent = titleContent;
+				actionBar.titleLayout = titleLayout;
+				overlayControls = false;
+			}
+			else
+			{
+				if (actionContentInvalidated)
+				{
+					actionBar.actionContent = view && view.actionContent ? 
+						view.actionContent : actionContent;
+					actionContentInvalidated = false;
+				}
+				
+				if (actionLayoutInvalidated)
+				{
+					actionBar.actionLayout = view && view.actionLayout ? 
+						view.actionLayout : actionLayout;
+					actionLayoutInvalidated = false;
+				}
+				
+				if (navigationContentInvalidated)
+				{
+					actionBar.navigationContent = view && view.navigationContent ? 
+						view.navigationContent : navigationContent;
+					navigationContentInvalidated = false;
+				}
+				
+				if (navigationLayoutInvalidated)
+				{
+					actionBar.navigationLayout = view && view.navigationLayout ? 
+						view.navigationLayout : navigationLayout;
+					navigationLayoutInvalidated = false;
+				}
+				
+				if (titleInvalidated)
+				{
+					actionBar.title = view && view.title ? view.title : title;
+					titleInvalidated = false;
+				}
+				
+				if (titleContentInvalidated)
+				{
+					actionBar.titleContent = view && view.titleContent ? 
+						view.titleContent : titleContent;
+					titleContentInvalidated = false;
+				}
+				
+				if (titleLayoutInvalidated)
+				{
+					actionBar.titleLayout = view && view.titleLayout ? 
+						view.titleLayout : titleLayout;
+					titleLayoutInvalidated = false;
+				}
+				
+				if (overlayControlsInvalidated)
+				{
+					if (overlayControls != view.overlayControls)
+					{
+						overlayControls = view.overlayControls;
+						
+						// We need to call super commitProperties() so that the new state is applied
+						super.commitProperties();
+					}
+					
+					overlayControlsInvalidated = false;
+				}
+				
+				actionBar.visible = actionBar.includeInLayout = view && view.actionBarVisible;
+				actionBarVisibilityInvalidated = false;
+				
+				actionBar.invalidateSize();
+				actionBar.invalidateDisplayList();
+			}
+		}
+		
+		/**
+		 *  @private
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		private function view_propertyChangeHandler(event:PropertyChangeEvent):void
+		{
+			var property:Object = event.property;
+			
+			// Check for actionBar related property changes
+			if (actionBar)
+			{
+				var propertyInvalidated:Boolean = true;
+				
+				if (property == "title")
+					titleInvalidated = true;
+				else if (property == "titleContent")
+					titleContentInvalidated = true;
+				else if (property == "titleLayout")
+					titleLayoutInvalidated = true;
+				else if (property == "actionContent")
+					actionContentInvalidated = true;
+				else if (property == "actionLayout")
+					actionLayoutInvalidated  = true;
+				else if (property == "navigationContent")
+					navigationContentInvalidated = true;
+				else if (property == "navigationLayout")
+					navigationLayoutInvalidated  = true;
+				else
+					propertyInvalidated = false;
+				
+				if (propertyInvalidated)
+					invalidateProperties();
+			}
+			
+			if (property == "overlayControls")
+			{
+				overlayControlsInvalidated = true;
+				invalidateProperties();
+			}
+		}
+		
+		/**
+		 *  @private
+		 *  
+		 *  @langversion 3.0
+		 *  @playerversion AIR 2.5
+		 *  @productversion Flex 4.5
+		 */
+		override protected function partAdded(partName:String, instance:Object):void
+		{
+			super.partAdded(partName, instance);
+			
+			// If the actionBar changes, need to reset the properties on it
+			if (instance == actionBar)
+			{
+				actionContentInvalidated = true;
+				actionLayoutInvalidated = true;
+				navigationContentInvalidated = true;
+				navigationLayoutInvalidated = true;
+				titleInvalidated = true;
+				titleContentInvalidated = true;
+				titleLayoutInvalidated = true;
+				
+				invalidateProperties();   
+			}
+		}
+		
+		/**
+		 *  @private
+		 */
+		override protected function partRemoved(partName:String, instance:Object):void
+		{
+			super.partRemoved(partName, instance);
+			
+			// Clear out all the content that is within the actionBar
+			if (instance == actionBar)
+			{
+				actionBar.actionContent = null;
+				actionBar.actionLayout = null;
+				actionBar.titleContent = null;
+				actionBar.titleLayout = null;
+				actionBar.navigationContent = null;
+				actionBar.navigationContent = null;
+			}
+		}
+	}
+}
\ No newline at end of file

Added: incubator/flex/whiteboard/tink/iview/src/org/apache/spark/components/ViewNavigator.png
URL: http://svn.apache.org/viewvc/incubator/flex/whiteboard/tink/iview/src/org/apache/spark/components/ViewNavigator.png?rev=1230830&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/flex/whiteboard/tink/iview/src/org/apache/spark/components/ViewNavigator.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream