256 lines
5.9 KiB
JavaScript
256 lines
5.9 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.
|
|
*
|
|
* @flow
|
|
*/
|
|
'use strict';
|
|
|
|
const NavigationExampleRow = require('./NavigationExampleRow');
|
|
const React = require('react');
|
|
const ReactNative = require('react-native');
|
|
|
|
/**
|
|
* Basic example that shows how to use <NavigationTransitioner /> and
|
|
* <Animated.View /> to build a stack of animated scenes that render the
|
|
* navigation state.
|
|
*/
|
|
|
|
|
|
import type {
|
|
NavigationSceneRendererProps,
|
|
NavigationState,
|
|
NavigationTransitionProps,
|
|
NavigationTransitionSpec,
|
|
} from 'NavigationTypeDefinition';
|
|
|
|
const {
|
|
Component,
|
|
PropTypes,
|
|
} = React;
|
|
|
|
const {
|
|
Animated,
|
|
Easing,
|
|
NavigationExperimental,
|
|
ScrollView,
|
|
StyleSheet,
|
|
} = ReactNative;
|
|
|
|
const {
|
|
PropTypes: NavigationPropTypes,
|
|
StateUtils: NavigationStateUtils,
|
|
Transitioner: NavigationTransitioner,
|
|
} = NavigationExperimental;
|
|
|
|
function reducer(state: ?NavigationState, action: any): NavigationState {
|
|
if (!state) {
|
|
return {
|
|
index: 0,
|
|
routes: [{key: 'route-1'}],
|
|
};
|
|
}
|
|
|
|
switch (action) {
|
|
case 'push':
|
|
const route = {key: 'route-' + (state.routes.length + 1)};
|
|
return NavigationStateUtils.push(state, route);
|
|
case 'pop':
|
|
return NavigationStateUtils.pop(state);
|
|
}
|
|
return state;
|
|
}
|
|
|
|
class Example extends Component {
|
|
state: NavigationState;
|
|
constructor(props: any, context: any) {
|
|
super(props, context);
|
|
this.state = reducer();
|
|
}
|
|
|
|
render(): ReactElement<any> {
|
|
return (
|
|
<ExampleNavigator
|
|
navigationState={this.state}
|
|
navigate={action => this._navigate(action)}
|
|
/>
|
|
);
|
|
}
|
|
|
|
_navigate(action: any): boolean {
|
|
if (action === 'exit') {
|
|
// Exits the example. `this.props.onExampleExit` is provided
|
|
// by the UI Explorer.
|
|
this.props.onExampleExit && this.props.onExampleExit();
|
|
return false;
|
|
}
|
|
|
|
const state = reducer(this.state, action);
|
|
if (state === this.state) {
|
|
return false;
|
|
}
|
|
|
|
this.setState(state);
|
|
return true;
|
|
}
|
|
|
|
// 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._navigate('pop');
|
|
}
|
|
}
|
|
|
|
class ExampleNavigator extends Component {
|
|
props: {
|
|
navigate: Function,
|
|
navigationState: NavigationState,
|
|
};
|
|
|
|
static propTypes: {
|
|
navigationState: NavigationPropTypes.navigationState.isRequired,
|
|
navigate: PropTypes.func.isRequired,
|
|
};
|
|
|
|
render(): ReactElement<any> {
|
|
return (
|
|
<NavigationTransitioner
|
|
navigationState={this.props.navigationState}
|
|
render={(transitionProps) => this._render(transitionProps)}
|
|
configureTransition={this._configureTransition}
|
|
/>
|
|
);
|
|
}
|
|
|
|
_render(
|
|
transitionProps: NavigationTransitionProps,
|
|
): Array<ReactElement<any>> {
|
|
return transitionProps.scenes.map((scene) => {
|
|
const sceneProps = {
|
|
...transitionProps,
|
|
scene,
|
|
};
|
|
return this._renderScene(sceneProps);
|
|
});
|
|
}
|
|
|
|
_renderScene(
|
|
sceneProps: NavigationSceneRendererProps,
|
|
): ReactElement<any> {
|
|
return (
|
|
<ExampleScene
|
|
{...sceneProps}
|
|
key={sceneProps.scene.key}
|
|
navigate={this.props.navigate}
|
|
/>
|
|
);
|
|
}
|
|
|
|
_configureTransition(): NavigationTransitionSpec {
|
|
const easing: any = Easing.inOut(Easing.ease);
|
|
return {
|
|
duration: 500,
|
|
easing,
|
|
};
|
|
}
|
|
}
|
|
|
|
class ExampleScene extends Component {
|
|
props: NavigationSceneRendererProps & {
|
|
navigate: Function,
|
|
};
|
|
|
|
static propTypes = {
|
|
...NavigationPropTypes.SceneRendererProps,
|
|
navigate: PropTypes.func.isRequired,
|
|
};
|
|
|
|
render(): ReactElement<any> {
|
|
const {scene, navigate} = this.props;
|
|
return (
|
|
<Animated.View
|
|
style={[styles.scene, this._getAnimatedStyle()]}>
|
|
<ScrollView style={styles.scrollView}>
|
|
<NavigationExampleRow
|
|
text={scene.route.key}
|
|
/>
|
|
<NavigationExampleRow
|
|
text="Push Route"
|
|
onPress={() => navigate('push')}
|
|
/>
|
|
<NavigationExampleRow
|
|
text="Pop Route"
|
|
onPress={() => navigate('pop')}
|
|
/>
|
|
<NavigationExampleRow
|
|
text="Exit NavigationTransitioner Example"
|
|
onPress={() => navigate('exit')}
|
|
/>
|
|
</ScrollView>
|
|
</Animated.View>
|
|
);
|
|
}
|
|
|
|
_getAnimatedStyle(): Object {
|
|
const {
|
|
layout,
|
|
position,
|
|
scene,
|
|
} = this.props;
|
|
|
|
const {
|
|
index,
|
|
} = scene;
|
|
|
|
const inputRange = [index - 1, index, index + 1];
|
|
const width = layout.initWidth;
|
|
const translateX = position.interpolate({
|
|
inputRange,
|
|
outputRange: ([width, 0, -10]: Array<number>),
|
|
});
|
|
|
|
return {
|
|
transform: [
|
|
{ translateX },
|
|
],
|
|
};
|
|
}
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
scene: {
|
|
backgroundColor: '#E9E9EF',
|
|
bottom: 0,
|
|
flex: 1,
|
|
left: 0,
|
|
position: 'absolute',
|
|
right: 0,
|
|
shadowColor: 'black',
|
|
shadowOffset: {width: 0, height: 0},
|
|
shadowOpacity: 0.4,
|
|
shadowRadius: 10,
|
|
top: 0,
|
|
},
|
|
scrollView: {
|
|
flex: 1,
|
|
},
|
|
});
|
|
|
|
module.exports = Example;
|