mirror of
https://github.com/status-im/react-native.git
synced 2025-01-13 19:15:05 +00:00
Add example for <NavigationTransitioner />
Summary: Add an example for <NavigationTransitioner /> that shows how to use <NavigationTransitioner /> and <Animated.View /> to build a stack of animated scenes that render the navigation state. This also defines the generic method for NavigationTransitioner to render scenes. Reviewed By: ericvicenti Differential Revision: D3422322 fbshipit-source-id: b9ff4c5102442a110739a546565552496349d473
This commit is contained in:
parent
c57bac4767
commit
bdb8efdd66
@ -35,6 +35,7 @@ const View = require('View');
|
||||
const EXAMPLES = {
|
||||
'CardStack + Header + Tabs Example': require('./NavigationCardStack-NavigationHeader-Tabs-example'),
|
||||
'CardStack Example': require('./NavigationCardStack-example'),
|
||||
'Transitioner + Animated View Example': require('./NavigationTransitioner-AnimatedView-example'),
|
||||
};
|
||||
|
||||
const EXAMPLE_STORAGE_KEY = 'NavigationExperimentalExample';
|
||||
|
@ -0,0 +1,255 @@
|
||||
/**
|
||||
* 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],
|
||||
});
|
||||
|
||||
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;
|
Loading…
x
Reference in New Issue
Block a user