react-native/Examples/UIExplorer/js/NavigationExperimental/NavigationCardStack-example.js

199 lines
5.6 KiB
JavaScript

/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
'use strict';
const NavigationExampleRow = require('./NavigationExampleRow');
const React = require('react');
const ReactNative = require('react-native');
/**
* Basic example that shows how to use <NavigationCardStack /> to build
* an app with controlled navigation system.
*/
const {
NavigationExperimental,
ScrollView,
StyleSheet,
} = ReactNative;
const {
CardStack: NavigationCardStack,
StateUtils: NavigationStateUtils,
} = NavigationExperimental;
// Step 1:
// Define a component for your application.
class YourApplication extends React.Component {
// This sets up the initial navigation state.
constructor(props, context) {
super(props, context);
this.state = {
// This defines the initial navigation state.
navigationState: {
index: 0, // starts with first route focused.
routes: [{key: 'Welcome'}], // starts with only one route.
},
};
this._exit = this._exit.bind(this);
this._onNavigationChange = this._onNavigationChange.bind(this);
}
// User your own navigator (see Step 2).
render(): ReactElement {
return (
<YourNavigator
navigationState={this.state.navigationState}
onNavigationChange={this._onNavigationChange}
onExit={this._exit}
/>
);
}
// This handles the navigation state changes. You're free and responsible
// to define the API that changes that navigation state. In this exmaple,
// we'd simply use a `function(type: string)` to update the navigation state.
_onNavigationChange(type: string): void {
let {navigationState} = this.state;
switch (type) {
case 'push':
// push a new route.
const route = {key: 'route-' + Date.now()};
navigationState = NavigationStateUtils.push(navigationState, route);
break;
case 'pop':
navigationState = NavigationStateUtils.pop(navigationState);
break;
}
// NavigationStateUtils gives you back the same `navigationState` if nothing
// has changed. You could use that to avoid redundant re-rendering.
if (this.state.navigationState !== navigationState) {
this.setState({navigationState});
}
}
// Exits the example. `this.props.onExampleExit` is provided
// by the UI Explorer.
_exit(): void {
this.props.onExampleExit && this.props.onExampleExit();
}
// This public method is optional. If exists, the UI explorer will call it
// the "back button" is pressed. Normally this is the cases for Android only.
handleBackAction(): boolean {
return this._onNavigationChange('pop');
}
}
// Step 2:
// Define your own controlled navigator.
//
// +------------+
// +-+ |
// +-+ | |
// | | | |
// | | | Active |
// | | | Scene |
// | | | |
// +-+ | |
// +-+ |
// +------------+
//
class YourNavigator extends React.Component {
// This sets up the methods (e.g. Pop, Push) for navigation.
constructor(props: any, context: any) {
super(props, context);
this._onPushRoute = this.props.onNavigationChange.bind(null, 'push');
this._onPopRoute = this.props.onNavigationChange.bind(null, 'pop');
this._renderScene = this._renderScene.bind(this);
}
// Now use the `NavigationCardStack` to render the scenes.
render(): ReactElement {
return (
<NavigationCardStack
onNavigateBack={this._onPopRoute}
navigationState={this.props.navigationState}
renderScene={this._renderScene}
style={styles.navigator}
/>
);
}
// Render a scene for route.
// The detailed spec of `sceneProps` is defined at `NavigationTypeDefinition`
// as type `NavigationSceneRendererProps`.
_renderScene(sceneProps: Object): ReactElement {
return (
<YourScene
route={sceneProps.scene.route}
onPushRoute={this._onPushRoute}
onPopRoute={this._onPopRoute}
onExit={this.props.onExit}
/>
);
}
}
// Step 3:
// Define your own scene.
class YourScene extends React.Component {
render() {
return (
<ScrollView style={styles.scrollView}>
<NavigationExampleRow
text={'route = ' + this.props.route.key}
/>
<NavigationExampleRow
text="Push Route"
onPress={this.props.onPushRoute}
/>
<NavigationExampleRow
text="Pop Route"
onPress={this.props.onPopRoute}
/>
<NavigationExampleRow
text="Exit Card Stack Example"
onPress={this.props.onExit}
/>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
navigator: {
flex: 1,
},
scrollView: {
marginTop: 64
},
});
module.exports = YourApplication;