Add gesture handling for the card stack.

Reviewed By: ericvicenti

Differential Revision: D2995958

fb-gh-sync-id: f66759440b03072b650a572f011cadd06a0180d2
shipit-source-id: f66759440b03072b650a572f011cadd06a0180d2
This commit is contained in:
Hedger Wang
2016-03-01 18:44:58 -08:00
committed by Facebook Github Bot 2
parent 85801ef874
commit caac520952
6 changed files with 372 additions and 74 deletions

View File

@@ -29,33 +29,41 @@
const Animated = require('Animated');
const NavigationContainer = require('NavigationContainer');
const NavigationLinearPanResponder = require('NavigationLinearPanResponder');
const React = require('React');
const ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');
const StyleSheet = require('StyleSheet');
const View = require('View');
const ReactComponentWithPureRenderMixin = require('ReactComponentWithPureRenderMixin');
const {PropTypes} = React;
const {Directions} = NavigationLinearPanResponder;
import type {
NavigationParentState,
} from 'NavigationStateUtils';
import type {
Layout,
Position,
NavigationStateRenderer,
} from 'NavigationAnimatedView';
import type {
Direction,
OnNavigateHandler,
} from 'NavigationLinearPanResponder';
type AnimatedValue = Animated.Value;
type Props = {
direction: string,
direction: Direction,
index: number;
layout: Layout;
navigationState: NavigationParentState;
position: Position;
renderScene: NavigationStateRenderer;
navigationParentState: NavigationParentState,
navigationState: NavigationParentState,
position: Position,
onNavigate: ?OnNavigateHandler,
renderScene: NavigationStateRenderer,
};
type State = {
@@ -78,6 +86,39 @@ class AmimatedValueSubscription {
}
}
/**
* Class that provides the required information for the
* `NavigationLinearPanResponder`. This class must implement
* the interface `NavigationLinearPanResponderDelegate`.
*/
class PanResponderDelegate {
_props : Props;
constructor(props: Props) {
this._props = props;
}
getDirection(): Direction {
return this._props.direction;
}
getIndex(): number {
return this._props.navigationParentState.index;
}
getLayout(): Layout {
return this._props.layout;
}
getPosition(): Position {
return this._props.position;
}
onNavigate(action: {type: string}): void {
this._props.onNavigate && this._props.onNavigate(action);
}
}
/**
* Component that renders the scene as card for the <NavigationCardStack />.
*/
@@ -119,9 +160,8 @@ class NavigationCardStackItem extends React.Component {
const {
direction,
index,
navigationState,
navigationParentState,
position,
layout,
} = this.props;
const {
height,
@@ -161,8 +201,16 @@ class NavigationCardStackItem extends React.Component {
],
};
let panHandlers = null;
if (navigationParentState.index === index) {
const delegate = new PanResponderDelegate(this.props);
const panResponder = new NavigationLinearPanResponder(delegate);
panHandlers = panResponder.panHandlers;
}
return (
<Animated.View
{...panHandlers}
style={[styles.main, animatedStyle]}>
{this.props.renderScene(this.props)}
</Animated.View>
@@ -200,16 +248,12 @@ class NavigationCardStackItem extends React.Component {
}
}
const Directions = {
HORIZONTAL: 'horizontal',
VERTICAL: 'vertical',
};
NavigationCardStackItem.propTypes = {
direction: PropTypes.oneOf([Directions.HORIZONTAL, Directions.VERTICAL]),
index: PropTypes.number.isRequired,
layout: PropTypes.object.isRequired,
navigationState: PropTypes.object.isRequired,
navigationParentState: PropTypes.object.isRequired,
position: PropTypes.object.isRequired,
renderScene: PropTypes.func.isRequired,
};
@@ -218,10 +262,6 @@ NavigationCardStackItem.defaultProps = {
direction: Directions.HORIZONTAL,
};
NavigationCardStackItem = NavigationContainer.create(NavigationCardStackItem);
NavigationCardStackItem.Directions = Directions;
const styles = StyleSheet.create({
main: {
backgroundColor: '#E9E9EF',
@@ -237,6 +277,4 @@ const styles = StyleSheet.create({
},
});
module.exports = NavigationCardStackItem;
module.exports = NavigationContainer.create(NavigationCardStackItem);