Not applicable.
It is recommended that you read the ViewNavigator Specification before reading this spec.
With the introduction of ViewNavigator
, developers are able to dynamically present and navigate content in their application. To aid in the development of rich user interfaces, the ability to apply effects to these content changes is required. View transitions are a new feature to the mobile framework that help solve this by providing the capability to run animations on view objects in response to navigation operations exposed by ViewNavigator
. View transitions are ultimately responsible for animating from one view to another, as well as the visual changes applied to the ViewNavigator
's action bar and tab bar.
The Flex Framework will ship with stock Slide, Flip, CrossFade, and Zoom view transitions for developers to use. A developer can customize these transitions or create their own transition and then apply them to any navigation operation.
View transitions are not related to standard Flex 4 transitions in any way. They cannot be defined in MXML and do not interact with states. View transitions can only be triggered by navigation operations of ViewNavigator
. View transitions are not a new effects or transitions framework. The do however leverage the spark effects framework to create and choreograph view animations.
ViewNavigator
. This should be managed by ViewNavigator
.ViewNavigator
component. His application consists of two views that the user can navigate between. As the user advances between each view, a slide transition is automatically played by the ViewNavigator
without John doing any extra work to configure it.ViewNavigator
instance).ViewTransitionBase
to create a view transition that creates her custom 3D effect.A ViewTransitionBase
class will be provided, defining the API that the ViewNavigator
will leverage when initializing and managing transitions during view navigation.
The ViewTransitionBase
class defines the following public properties:
[[ span class=u'indent' ]][[ quote ]] || Property \ || Info \ || Description \ || | startView
\ | read/write \ | Set by view navigator, reference to original view. \ | | endView
\ | read/write \ | Set by view navigator, reference to pending view. \ | | navigator
\ | read/write \ | Set by view navigator, reference to owning navigator managing the views. \ | | duration
\ | read/write \ | Specifies duration of the transition (ms). \ | | easer
\ | read/write \ | Specifies IEaser
used for the transition. \ |
[[ /quote ]][[ /span ]]
The ViewTransitionBase
class defines the following public methods:
[[ span class=u'indent' ]][[ quote ]] || Method \ || Description \ || | captureStartValues()
\ | Preparation phase method invoked by owning navigator. \ | | captureEndValues()
\ | Preparation phase method invoked by owning navigator. \ | | prepareForPlay()
\ | Preparation phase method invoked by owning navigator. \ | | play()
\ | Execution phase method invoked by owning navigator. \ |
[[ /quote ]][[ /span ]]
The ViewTransitionBase
class defines the following events:
[[ span class=u'indent' ]][[ quote ]] || Method \ || Description \ || | transitionStart
\ | Denotes that the transition has started, at this point the effect
property should be valid. \ | | transitionEnd
\ | Denotes that the transition is complete. \ |
[[ /quote ]][[ /span ]]
View transitions are responsible for mediating a transition when the user navigates from one view to another when one of the navigator's navigation operations are invoked, e.g.:
pushView()
popView()
popToFirstView()
popAll()
replaceView()
The primary role of the view transition is to create and play the various effects necessary to transition the old view away and the new view into position as well as animating content changes to the owning navigator's action bar and tab bar. During its lifetime, a transition will maintain a reference to the navigator, the current view and the view that the navigator is transitioning to.
A view transition goes through two main phases, the preparation phase and the execution phase:
Preparation phase:
The preparation phase consists of (3) steps, all orchestrated by the owning ViewNavigator
:
captureStartValues()
is invoked on the transition. At this time the ViewNavigator
has created the new view but has yet to fully validate the new view or update the content of the action bar and tab bar. This step is provided to allow the transition to capture the start values for all the components that may play a role in the transition. Note also that since there is only one instance of the action and tab bars, it is at this point that the transition should capture any bitmap representations of these components if they will be animated.captureEndValues()
is invoked on the transition. At this point the new view has been fully realized and validated and the action bar and tab bar content reflect the state of the new view. It is at this point that the transition is to capture any values it requires from the pending view. In addition any bitmaps reflecting the state of the new view, tab bar, or action bar are captured.prepareForPlay()
is invoked on the transition. This is called to allow the transition to initialize the Effect
instance which will be used to animate the necessary components of the transition. In addition the transition may choose to parent any temporary display objects in the DOM that are necessary to facilitate the transitions (such as bitmap snapshots, or temporary containers required for transformations).Execution phase:
The execution phase begins when play()
is invoked on the transition by the owning ViewNavigator
. At this point, the new view has been completely created and validated, and the action bar and tab bar content reflects the properties set by the new view. A "start" event is dispatched by the transition and the IEffect
instance created during the preparation phase is now invoked via its play()
method.
So what exactly does the execution phase entail?
The process of transitioning from one navigator view to another is wholly freeform. Transitioning views can be complex. In general transitions aren't simply performing a raster based transition of the previous view's contents with the new view's contents (though some simple transitions may do just that). View transitions may also perform subtle choreographed animations on individual action bar elements for instance, fading some in while some fade out, or sliding some in while some slide out.The mechanism of choreography is fully up to the transition itself though in most cases Spark Effect sequences are used. In some cases the target of these animations will be bitmap snapshots (as is required for the action bar because a single action bar is shared by both the incoming and outgoing views), while others will animate properties of the previous View
instance and new View
instance directly. Note that when animating the views directly on screen it is considered best practice to leverage cacheAsBitmap
and cacheAsBitmapMatrix
as appropriate to ensure optimal performance.
When all the effects are complete, the view transition is required to dispatch an "end" event, to notify the navigator that the transition is finished. As a convenience, transitions based on ViewTransitionBase
can simply call transitionComplete() which will dispatch the TRANSITION_END event. It is important that the transition cleans up any temporary objects and remove listeners it has created before dispatching the completion event.
Once transitionComplete()
is called, the ViewNavigator
object finalizes the view changing process and resets the transition to its unitialized state (setting any navigator or view references to null
).
The ViewTransitionBase
class serves as the base class for all stock view transitions and is not intended to be used as a transition on its own.
The ViewTransitionBase
class provides convenience functionality shared by all stock SDK view transitions:
Default Action Bar Transition:
Unless the transitionControlsWithContent property is set on the transition, or unless a consolidated transition (one where views cannot be transitioned independently from control bars) is deemed necessary, a default action bar transition will occur, which animates any action bar content that changed between views. The default action bar transition simply fades any changing content out and fading new content in as a simple "slide".
A "full screen" or consolidated transition is deemed necessary (and as such the default action bar transition will be suppressed), if the action bar changes size between views, or if one or both views do not have an action bar, or if the view's overlayControls
property changes between views.
A ViewTransitionBase
based transition can affect the behavior of the default action bar transition with a pair of helper properties. The actionBarTransitionMode
property can be used to specify whether or not the default action bar transition simply cross fades the action bar elements, performs a "slide" transition while fading, or none of the above. The actionBarTransitionDirection
property can be used to hint the slide direction of the default action bar transition. These properties must be set by transitions prior to invocation of the base prepareForPlay() method. The action bar transition style is noted below with each of the stock SDK transitions.
Effect Preparation Helpers:
The ViewTransitionBase
class's prepareForPlay()
method automatically builds up a single Parallel
effect instance by invoking three helper methods during the preparation phase. Stock view transitions (or custom transitions) can override createViewEffect()
, createActionBarEffect()
and createTabBarEffect()
to customize the effect used to transition the views, action bar, or tab bar respectively.
The following stock view transitions will be provided by the mobile SDK:
[[ span class=u'indent' ]]
The SlideViewTransition
is a stock transition that slides views into and out of position while transitioning views. This transition can be configured to work in one of three modes, and in one of four directions.
modes:
[[ quote ]]
SlideViewTransitionMode.PUSH: The previous view slides away as the new view slides in.
SlideViewTransitionMode.COVER - The new view slides in to cover the previous view.
SlideViewTransitionMode.UNCOVER - The previous view slides away to reveal the new view.
[[ /quote ]]
directions:
[[ quote ]]
ViewTransitionDirection.UP: The views slide towards the top of the navigator.
ViewTransitionDirection.DOWN: The views slide towards the bottom of the navigator.
ViewTransitionDirection.LEFT: The views slide towards the left of the navigator.
ViewTransitionDirection.RIGHT: The views slide towards the right of the navigator.
[[ /quote ]]
The SlideViewTransition
makes use of ViewTransitionBase
's default action bar transition when appropriate unless a full screen transition is required or requested. The default action bar transition mode will be to slide/fade out action bar elements while new elements slide/fade in, and in the direction of the view transition itself.
The FlipViewTransition
is a stock transition that will animate the 3D transform of the old and new views in one of two ways, depending on the mode.
modes:
[[ quote ]]
FlipViewTransitionMode.CARD: The previous view flips at its center point as the new view is revealed on the other side.
FlipViewTransitionMode.CUBE - The previous view is transformed away like the face on a rotating cube, as the new view is revealed as the adjacent face of the cube.
[[ /quote ]]
Much like the , the can transition in one of four directions:
[[ quote ]]
ViewTransitionDirection.UP: The views flip towards the top of the navigator.
ViewTransitionDirection.DOWN: The views flip towards the bottom of the navigator.
ViewTransitionDirection.LEFT: The views flip towards the left of the navigator.
ViewTransitionDirection.RIGHT: The views flip towards the right of the navigator.
[[ /quote ]]
The FlipViewTransition
makes use of ViewTransitionBase
's default action bar transition when appropriate unless a full screen transition is required or requested. The default action bar transition mode will be to slide/fade out action bar elements while new elements slide/fade in, and in the direction of the view transition itself.
The CrossFadeViewTransition
fades the old view out as the new view fades in. It always fades to the original alpha values defined on the view which normally would be '1'.
The CrossFadeViewTransition
makes use of ViewTransitionBase
's default action bar transition when appropriate unless a full screen transition is required or requested. The default action bar transition mode fade out action bar elements while new elements fade in.
The ZoomViewTransition
will either zoom/scale the new view in to replace the old view, or will zoom/scale the old view out to reveal the new view.
[[ quote ]]
ZoomTransitionMode.IN: The new view is zoomed/scaled up and in to replace existing view (centered transform).
ZoomTransitionMode.OUT - The original view is zoomed/scaled down and out revealing new view (centered transform).
[[ /quote ]]
[[ /span ]]
The ZoomViewTransition
makes use of ViewTransitionBase
's default action bar transition when appropriate unless a full screen transition is required or requested. The default action bar transition mode fade out action bar elements while new elements fade in.
All transitions will have a duration
and easer
property that allow developers to affect the basic characteristics of the primary transition animation. In addition, each transition will provide specific properties that allow further customization. For example, a slide transition allows the developer to decide the direction the animation slides.
View transitions will not support orientation transitions. There is no direct support for this functionality in the framework or runtime.
During a view transition, the ViewNavigator
will have its mouseEnabled and mouseChildren properties set to false and restored afterwords. This is to prevent user interaction during a view transition.
package spark.transitions
{
/**
* Dispatched when the transition starts.
*/
<a href="Event%28name%3D%26quot%3BtransitionStart%26quot%3B%2C%20type%3D%26quot%3Bmx.events.FlexEvent%26quot%3B%29">Event(name="transitionStart", type="mx.events.FlexEvent")</a>
/**
* Dispatched when the transition is complete.
*/
<a href="Event%28name%3D%26quot%3BtransitionEnd%26quot%3B%2C%20type%3D%26quot%3Bmx.events.Event%26quot%3B%29">Event(name="transitionEnd", type="mx.events.Event")</a>
public class ViewTransitionBase extends EventDispatcher
{
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// duration
//----------------------------------
/**
* Duration of the transition in milliseconds. The default may vary
* depending on the transition.
*/
public function get duration():Number;
public function set duration(value:Number):void;
//----------------------------------
// easer
//----------------------------------
/**
* The easing behavior for this transition.
* This IEaser object is used to convert the elapsed fraction of
* the animation into an eased fraction, which is then used to
* calculate the value at that eased elapsed fraction.
*
* @default @default spark.effects.easing.Sine(.5)
*/
public function get easer():IEaser;
public function set easer(value:IEaser):void;
//----------------------------------
// endView
//----------------------------------
/**
* The reference to the view that the navigator is transitioning
* to, set by the owning ViewNavigator itself. This can be null.
*
* @default null
*/
public function get endView():View;
public function set endView(value:View):void;
//----------------------------------
// transitionControlsWithContent
//----------------------------------
/**
* When set to true, the primary view transition
* is used to transition the navigator in its entirety,
* and sub-transitions such as the action bar or
* tab bar transitions are not performed.
*
* This property may be set to true by the transition
* itself if it's determined that the action bar or
* tab bar does not exist in one of the two views or
* if the tab bar or action bar changes size.
*
* @default false
*/
public function get transitionControlsWithContent():Boolean;
public function set transitionControlsWithContent(value:Boolean):void;
//----------------------------------
// navigator
//----------------------------------
/**
* Reference to the owning ViewNavigator instance set by the owning
* ViewNavigator.
*/
public function get navigator():ViewNavigator;
public function set navigator(value:ViewNavigator):void;
//----------------------------------
// startView
//----------------------------------
/**
* The currently active view of the view navigator, set by the owning
* view navigator itself. This can be null.
*
* @default null
*/
public function get startView():View;
public function set startView(value:View):void;
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* This method is called by the ViewNavigator during the preparation phase of a transition.
* It is invoked when the new view has been fully realized and validated and the
* action bar and tab bar content reflect the state of the new view. It is at
* this point that the transition is to capture any values it requires from the
* pending view. In addition any bitmaps reflecting the state of the new view, tab bar,
* or action bar should be captured if required for animation.
*/
public function captureStartValues():void;
/**
* This method is called by the ViewNavigator during the preparation phase of a transition.
* It is invoked when the new view has been fully realized and validated and the
* action bar and tab bar content reflect the state of the new view. It is at
* this point that the transition is to capture any values it requires from the
* pending view. In addition any bitmaps reflecting the state of the new view, tab bar,
* or action bar should be captured if required for animation.
*/
public function captureEndValues():void;
/**
* Called by the default prepareForPlay() implementation, this method
* is responsible for creating the spark effect that should be played on the
* action bar when the transition starts. This method should be
* overridden by sub classes if a custom action bar effect is
* required. By default, this returns a basic action bar effect.
*/
protected function createActionBarEffect():IEffect;
/**
* Called by the default prepareForPlay() implementation, this method
* is responsible for creating the spark effect that should be played
* on the tab bar when the transition starts. This method should be
* overridden by sub classes. By default, this returns null.
*/
protected function createTabBarEffect():IEffect;
/**
* Called by the default prepareForPlay() implementation, this method
* is responsible for creating the spark effect that should be played
* on the current and next view when the transition starts. This method
* should be overridden by sub classes. By default, this returns null.
*/
protected function createViewEffect():IEffect;
/**
* This method is called by the ViewNavigator when the transition
* should begin animating. At this time the transition should dispatch an
* FlexEvent.TRANSITION_START event.
*/
public function play():void;
/**
* This method is called by the ViewNavigator during the preparation phase of a
* transition. It gives the transition the chance to create and
* configure the underlying IEffect instance, or to add any helper
* elements to the display list (e.g. bitmap placeholders, temporary
* containers required during the transition, etc.).
*/
public function prepareForPlay():void;
/**
* Called by the transition to denote that the effect object
* has finished executing, dispatches a FlexEvent.TRANSITION_END event.
*/
protected function transitionComplete():void;
}
}
package spark.transitions
{
public class SlideViewTransition extends ViewTransitionBase
{
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//---------------------------------
// direction
//---------------------------------
/**
* Specifies the direction of slide transition.
*
* @default ViewTransitionDirection.LEFT
*/
public function get direction():String;
public function set direction(value:String):void;
//---------------------------------
// mode
//---------------------------------
/**
* Specifies the type of slide transition to perform.
*
* @default SlideViewTransitionMode.PUSH
*/
public function get mode():String;
public function set mode(value:String):void;
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @inheritDoc
*/
override public function createViewEffect():IEffect;
}
}
package spark.transitions
{
public class FlipViewTransition extends ViewTransitionBase
{
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//---------------------------------
// direction
//---------------------------------
/**
* Specifies the direction of flip transition.
*
* @default ViewTransitionDirection.LEFT
*/
public function get direction():String;
public function set direction(value:String):void;
//---------------------------------
// mode
//---------------------------------
/**
* Specifies the type of flip transition to perform.
*
* @default FlipViewTransitionMode.CARD
*/
public function get mode():String;
public function set mode(value:String):void;
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @inheritDoc
*/
override public function createViewEffect():IEffect;
}
}
package spark.transitions
{
public class CrossFadeViewTransition extends ViewTransitionBase
{
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @inheritDoc
*/
override public function createViewEffect():IEffect;
}
}
package spark.transitions
{
public class ZoomViewTransition extends ViewTransitionBase
{
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//---------------------------------
// minimumScale
//---------------------------------
/**
* Specifies the minimum scale of the zoomed view (represents when the
* view is first visible when zooming in or last visible when zooming
* out).
*
* @default .25
*/
public function get minimumScale():Number;
public function set minimumScale(value:Number):void;
//---------------------------------
// mode
//---------------------------------
/**
* Specifies the type of zoom transition to perform.
*
* @default ZoomViewTransitionMode.IN
*/
public function get mode():String;
public function set mode(value:String):void;
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @inheritDoc
*/
override public function createViewEffect():IEffect;
}
}
package spark.transitions
{
public class SlideViewTransitionMode
{
//--------------------------------------------------------------------------
//
// Class constants
//
//--------------------------------------------------------------------------
/**
* The new view slides in to cover the previous view.
*/
public static const COVER:String = "cover";
/**
* The previous view slides away as the new view slides in.
*/
public static const PUSH:String = "push";
/**
* The previous view slides away to reveal the new view.
*/
public static const UNCOVER:String = "uncover";
}
}
package spark.transitions
{
public class FlipViewTransitionMode
{
//--------------------------------------------------------------------------
//
// Class constants
//
//--------------------------------------------------------------------------
/**
* The previous view flips at its center point as the new view is revealed
* on the other side.
*/
public static const CARD:String = "card";
/**
* The previous view is transformed away like the face on a rotating cube, as
* the new view is revealed as the adjacent face of the cube.
*/
public static const CUBE:String = "cube";
}
}
package spark.transitions
{
public class ZoomViewTransitionMode
{
//--------------------------------------------------------------------------
//
// Class constants
//
//--------------------------------------------------------------------------
/**
* The new view is zoomed/scaled up and in to replace existing
* view (centered transform).
*/
public static const IN:String = "in";
/**
* The original view is zoomed/scaled down and out revealing new
* view (centered transform).
*/
public static const OUT:String = "out";
}
}
package spark.transitions
{
public class ViewTransitionDirection
{
//--------------------------------------------------------------------------
//
// Class constants
//
//--------------------------------------------------------------------------
/**
* Transition animates upward.
*/
public static const UP:String = "up";
/**
* Transition animates downward.
*/
public static const DOWN:String = "down";
/**
* Transition animates to the left.
*/
public static const LEFT:String = "left";
/**
* Transition animates to the right.
*/
public static const RIGHT:String = "right";
}
}
package mx.events
{
public class FlexEvent extends Event
{
//--------------------------------------------------------------------------
//
// Class constants
//
//--------------------------------------------------------------------------
...
/**
* Denotes that transition has started.
*/
public static const TRANSITION_START:String = "transitionStart";
/**
* Denotes that transition is complete.
*/
public static const TRANSITION_END:String = "transitionEnd";
...
}
}
package spark.components
{
public class ViewNavigator extends ViewNavigatorBase
{
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//---------------------------------
// defaultPushTransition
//---------------------------------
/**
* Specifies the default view transition for push navigation operations.
*
* @default new SlideViewTransition()
*/
public function get defaultPushTransition():ViewTransitionBase
public function set defaultPushTransition(value:ViewTransitionBase):void;
//---------------------------------
// defaultPopTransition
//---------------------------------
/**
* Specifies the default view transition for pop navigation operations.
*
* @default new SlideViewTransition()
*/
public function get defaultPopTransition():ViewTransitionBase
public function set defaultPopTransition(value:ViewTransitionBase):void;
}
}
The following example details how one can specify that a 3D cube flip transition be used for a given navigator push operation:
import spark.transitions.FlipViewTransition;
import spark.transitions.FlipViewTransitionMode;
...
var cubeFlip:FlipViewTransition = new FlipViewTransition();
cubeFlip.duration = 500;
cubeFlip.mode = FlipViewTransitionMode.3D;
myNavigator.pushView(ViewClass, viewData, null, cubeFlip);
...
The example below demonstrates how to set the default transitions for a given navigator instance.
import spark.transitions.SlideViewTransition;
...
var coverForward:SlideViewTransition = new SlideViewTransition();
coverForward.mode = SlideViewTransitionMode.COVER;
coverForward.direction = ViewTransitionDirection.LEFT;
var uncoverBackward:SlideViewTransition = new SlideViewTransition();
uncoverBackward.mode = SlideViewTransitionMode.UNCOVER;
uncoverBackward.direction = ViewTransitionDirection.RIGHT;
myNavigator.defaultPushTransition = coverForward;
myNavigator.defaultPopTransition = uncoverBackward;
...
As part of this feature work, two properties will be exposed on ViewNavigator
to allow developers to specify a default push and pop transition. By default the SlideViewTransition
in "push" mode is leveraged by ViewNavigator
.
For testing purposes an mx_internal property (activeTransition
) will be exposed on ViewNavigator
to expose the currently active view transition instance, available at the time the transitionStart
event is dispatched by the ViewNavigator
. In addition an mx_internal effect
property will be available on ViewTransitionBase
itself, which will provide access to the effect instance directly responsible for animating the currently effect sequence. This will allow testers to directly affect the running transition effect (pausing, setting playHead position etc.)
The alwaysCreateDisplayObject
property on GraphicElement
will now be public (was mx_internal)...this will allow us to host and animate placeholder BitmapImage
instances rather than spark Image
components.
Not applicable.
Not applicable.
Not applicable.
Not applicable.
Not applicable.
There are a number of performance concerns when transitioning views, specifically we will ensure there are as few display objects transitioned as possible, that all view representations are cached as surfaces (via cacheAsBitmap), and all concurrent animations are kept to a minimum.
Not applicable.
Not applicable.
Not applicable.
Not applicable.
Transition performance may vary from device to device. We will ensure eventually that we are leveraging hardware rendering (GPU render mode) when possible and feasible.