`

How to use the Feathers ScreenNavigator component

 
阅读更多

来自:http://wiki.starling-framework.org/feathers/start

原文:http://wiki.starling-framework.org/feathers/screen-navigator

 

The ScreenNavigator class offers a powerful system for displaying screens or menus in your application and navigating between them. It supports navigation based on events (or as3-signals, if you prefer), and it can inject properties into screens as they are shown.

 

The Basics

Create a ScreenNavigator like this:

this._navigator = new ScreenNavigator();
this.addChild( this._navigator );

You may also set its width and height, but that's optional because the ScreenNavigator will automatically resize itself to fill the entire stage if you don't provide explicit dimensions.

To add a new screen to the navigator, call addScreen() and pass in a String indentifier for the screen along with a ScreenNavigatorItem:

this._navigator.addScreen( "mainMenu", new ScreenNavigatorItem( MainMenuScreen ) );

The first argument required by the ScreenNavigatorItem constructor is either a Class to instantiate or a DisplayObject that has already been instantiated. In general, your screen class, whether you instantiate it directly or allow the ScreenNavigatorItem to instantiate it, should extend Screen. This is not required, though.

In this case, MainMenuScreen is another class in our project. There are a couple more arguments that the constructor supports, and we'll look at them later.

To show a specific screen, call showScreen() and pass in the screen's identifier:

this._navigator.showScreen( "mainMenu" );

To access the currently visible screen, use the activeScreen property.

var mainMenu:MainMenuScreen = MainMenuScreen( this._navigator.activeScreen );

You can also use activeScreenID to get the String identifier for the active screen.

To make the ScreenNavigator show nothing, call clearScreen().

this._navigator.clearScreen();
 

Navigation

If a particular screen dispatches an event or a signal, the ScreenNavigator can use it to automatically navigate to another screen.

Before we get to that, let's make a couple of changes. First, let's move the main menu screen's identifier to a constant. Then, let's add a second screen.

private static const MAIN_MENU:String = "mainMenu";
private static const OPTIONS:String = "options";

The constants will help us avoid typing mistakes. Now, let's add the options screen.

this._navigator.addScreen( OPTIONS, new ScreenNavigatorItem( OptionsScreen ) );

Now that we have a second screen, let's allow the main menu to navigate to it.

 

With Signals

The second argument to the ScreenNavigatorItem constructor is an event map. We can map event types (or signals) to screen identifiers. Let's change the call where we added the main menu screen.

this._navigator.addScreen( MAIN_MENU, new ScreenNavigatorItem( MainMenuScreen,
{
	onOptions: OPTIONS
}));

Inside MainMenuScreen, there's a signal called onOptions that will automatically be detected when the ScreenNavigator reads the event map.

protected var _onOptions:Signal = new Signal( MainMenuScreen );
 
public function get onOptions():ISignal
{
	return this._onOptions;
}

The MainMenuScreen might dispatch onOptions like this:

protected function optionsButton_triggeredHandler( event:Event ):void
{
	this._onOptions.dispatch( this );
}

Now we can navigate to the options screen from the main menu screen. Let's modify the options screen item to navigate back.

 

With Events

Let's have the options screen dispatch an event instead of a signal to see how events may be used for navigation too. The ScreenNavigator automatically checks for a signal first, but if none is found, it will assume that an event is dispatched instead. Let's add a “complete” event to the event map for OptionsScreen.

this._navigator.addScreen( OPTIONS, new ScreenNavigatorItem( OptionsScreen,
{
	complete: MAIN_MENU
}));

Inside OptionsScreen, we'll dispatch an event when a button is pressed.

protected function optionsButton_triggeredHandler( event:Event ):void
{
	this.dispatchEventWith( Event.COMPLETE );
}

Now we can navigate to the options screen from the main menu and then we can navigate back.

 

With the owner property

The Screen class has an owner property that points to the ScreenNavigator. You can use this to call showScreen() directly, if you prefer not to use events or signals.

this.owner.showScreen( "anotherScreenID" );
 

Property Injection

The third argument you can pass to the ScreenNavigatorItem constructor is an initializer object. This is a set of key-value pairs that map to properties on the screen being defined. When the screen is shown, each of these properties will be passed to the screen. If you have multiple screens that need to share some data, this is a useful way to ensure that they each have access to it. For instance, you might have an OptionsData class that stores things like audio volume and other common options.

In our main app, we store the OptionsData instance.

this._optionsData = new OptionsData();

Then, when we add our OptionsScreen, we pass it the OptionsData instance in using the initializer.

this._navigator.addScreen( OPTIONS, new ScreenNavigatorItem( OptionsScreen,
{
	complete: MAIN_MENU
},
{
	optionsData: this._optionsData
}));

In OptionsScreen, we need to add a variable or a getter and setter for this data:

protected var _optionsData:OptionsData;
 
public function get optionsData():OptionsData
{
	return this._optionsData;
}
 
public function set optionsData( value:OptionsData ):void
{
	this._optionsData = value;
}

If you want to redraw when optionsData changes, you should invalidate the screen, and the draw() function will be called again:

public function set optionsData( value:OptionsData ):void
{
	this._optionsData = value;
	this.invalidate( INVALIDATION_FLAG_DATA );
}
 

Transitions

The ScreenNavigator class supports transition animations when changing screens. A number of useful transition “manager” classes are pre-defined in the feathers.motion.transitions package. Some of these track the history of screens to add a little extra context to their animations. For instance, the ScreenSlidingStackTransitionManager stores a stack of recent screens to intelligently choose the direction a screen slides in from when it is shown (either the left side or the right side).

To use the ScreenSlidingStackTransitionManager, we simply need to pass a ScreenNavigator instance to the constructor.

this._transitionManager = new ScreenSlidingStackTransitionManager( this._navigator );

Many of the transition managers expose some properties that can be used to adjust the animation. For instance, the ScreenSlidingStackTransitionManager exposes the duration of the animation and the easing function.

this._transitionManager.duration = 0.4;
this._transitionManager.ease = Transitions.EASE_OUT_BACK;
 

Transition Events

The ScreenNavigator dispatches FeathersEventType.TRANSITION_START and FeathersEventType.TRANSITION_COMPLETE events when the transition starts and ends. You might listen to FeathersEventType.TRANSITION_COMPLETE to delay the initialization of your screen until the transition has completed. For instance, you might have other animations that need to play, but once the screen is fully visible.

this.owner.addEventListener( FeathersEventType.TRANSITION_COMPLETE, owner_transitionCompleteHandler );

The event listener might look like this:

private function owner_transitionCompleteHandler( event:Event ):void
{
    this.owner.removeEventListener( FeathersEventType.TRANSITION_COMPLETE, owner_transitionCompleteHandler );
 
    // finish initialization here
}

Note that the ScreenNavigator will dispatch the FeathersEventType.TRANSITION_START and FeathersEventType.TRANSITION_COMPLETE events when a screen is being removed too. You will need to remove event listeners meant to be called only when the screen is added if you don't want them to run again when the screen is removed.

 

Advanced Functionality

The ScreenNavigatorItem event map can be used for more than just navigation. You can also call a function when an event or signal is dispatched. Let's add a new signal to the main menu that will be dispatched when a “About Our Product” button is clicked. We want it to open a website in the browser.

this._navigator.addScreen( MAIN_MENU, new ScreenNavigatorItem( MainMenuScreen,
{
	onOptions: OPTIONS,
	onHomePage: mainMenuScreen_onHomePage
}));

The function receives the signal or event listener arguments.

protected function mainMenuScreen_onHomePage( sender:MainMenuScreen ):void
{
	navigateToURL( new URLRequest( "http://www.example.com/" ), "_blank" );
}
 

Related Links

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics