mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-09 22:51:57 +08:00
feat: add on transition end callback (#153)
This commit is contained in:
committed by
satyajit.happy
parent
fb9dbf9820
commit
51b1069d51
@@ -108,6 +108,8 @@ export type NavigationStackOptions = HeaderOptions &
|
||||
horizontal?: number;
|
||||
};
|
||||
disableKeyboardHandling?: boolean;
|
||||
onTransitionStart?: () => void;
|
||||
onTransitionEnd?: () => void;
|
||||
};
|
||||
|
||||
export type NavigationConfig = {
|
||||
|
||||
@@ -46,8 +46,8 @@ type Props = {
|
||||
renderScene: (props: { route: Route }) => React.ReactNode;
|
||||
headerMode: HeaderMode;
|
||||
onTransitionStart?: (
|
||||
curr: { index: number },
|
||||
prev: { index: number }
|
||||
current: { index: number },
|
||||
previous: { index: number }
|
||||
) => void;
|
||||
onGestureBegin?: () => void;
|
||||
onGestureCanceled?: () => void;
|
||||
@@ -60,7 +60,7 @@ type State = {
|
||||
scenes: HeaderScene<Route>[];
|
||||
progress: ProgressValues;
|
||||
layout: Layout;
|
||||
floaingHeaderHeight: number;
|
||||
floatingHeaderHeight: number;
|
||||
};
|
||||
|
||||
const dimensions = Dimensions.get('window');
|
||||
@@ -171,7 +171,7 @@ export default class Stack extends React.Component<Props, State> {
|
||||
// This is not a great heuristic here. We don't know synchronously
|
||||
// on mount what the header height is so we have just used the most
|
||||
// common cases here.
|
||||
floaingHeaderHeight: getDefaultHeaderHeight(layout),
|
||||
floatingHeaderHeight: getDefaultHeaderHeight(layout),
|
||||
};
|
||||
|
||||
private handleLayout = (e: LayoutChangeEvent) => {
|
||||
@@ -192,11 +192,32 @@ export default class Stack extends React.Component<Props, State> {
|
||||
private handleFloatingHeaderLayout = (e: LayoutChangeEvent) => {
|
||||
const { height } = e.nativeEvent.layout;
|
||||
|
||||
if (height !== this.state.floaingHeaderHeight) {
|
||||
this.setState({ floaingHeaderHeight: height });
|
||||
if (height !== this.state.floatingHeaderHeight) {
|
||||
this.setState({ floatingHeaderHeight: height });
|
||||
}
|
||||
};
|
||||
|
||||
private handleTransitionStart = ({
|
||||
route,
|
||||
current,
|
||||
previous,
|
||||
}: {
|
||||
route: Route;
|
||||
current: { index: number };
|
||||
previous: { index: number };
|
||||
}) => {
|
||||
const { onTransitionStart, descriptors } = this.props;
|
||||
const options = descriptors[route.key].options;
|
||||
|
||||
onTransitionStart && onTransitionStart(current, previous);
|
||||
options.onTransitionStart && options.onTransitionStart();
|
||||
};
|
||||
|
||||
private handleTransitionEnd = ({ route }: { route: Route }) => {
|
||||
const options = this.props.descriptors[route.key].options;
|
||||
options.onTransitionEnd && options.onTransitionEnd();
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
mode,
|
||||
@@ -212,13 +233,12 @@ export default class Stack extends React.Component<Props, State> {
|
||||
renderHeader,
|
||||
renderScene,
|
||||
headerMode,
|
||||
onTransitionStart,
|
||||
onGestureBegin,
|
||||
onGestureCanceled,
|
||||
onGestureEnd,
|
||||
} = this.props;
|
||||
|
||||
const { scenes, layout, progress, floaingHeaderHeight } = this.state;
|
||||
const { scenes, layout, progress, floatingHeaderHeight } = this.state;
|
||||
|
||||
const focusedRoute = navigation.state.routes[navigation.state.index];
|
||||
const focusedOptions = descriptors[focusedRoute.key].options;
|
||||
@@ -300,7 +320,7 @@ export default class Stack extends React.Component<Props, State> {
|
||||
onGestureCanceled={onGestureCanceled}
|
||||
onGestureEnd={onGestureEnd}
|
||||
gestureResponseDistance={gestureResponseDistance}
|
||||
floaingHeaderHeight={floaingHeaderHeight}
|
||||
floatingHeaderHeight={floatingHeaderHeight}
|
||||
hasCustomHeader={header === null}
|
||||
getPreviousRoute={getPreviousRoute}
|
||||
headerMode={headerMode}
|
||||
@@ -309,7 +329,8 @@ export default class Stack extends React.Component<Props, State> {
|
||||
renderScene={renderScene}
|
||||
onOpenRoute={onOpenRoute}
|
||||
onCloseRoute={onCloseRoute}
|
||||
onTransitionStart={onTransitionStart}
|
||||
onTransitionStart={this.handleTransitionStart}
|
||||
onTransitionEnd={this.handleTransitionEnd}
|
||||
onGoBack={onGoBack}
|
||||
direction={direction}
|
||||
transitionSpec={transitionSpec}
|
||||
|
||||
@@ -33,10 +33,12 @@ type Props = TransitionPreset & {
|
||||
onOpenRoute: (props: { route: Route }) => void;
|
||||
onCloseRoute: (props: { route: Route }) => void;
|
||||
onGoBack: (props: { route: Route }) => void;
|
||||
onTransitionStart?: (
|
||||
curr: { index: number },
|
||||
prev: { index: number }
|
||||
) => void;
|
||||
onTransitionStart?: (props: {
|
||||
route: Route;
|
||||
current: { index: number };
|
||||
previous: { index: number };
|
||||
}) => void;
|
||||
onTransitionEnd?: (props: { route: Route }) => void;
|
||||
onGestureBegin?: () => void;
|
||||
onGestureCanceled?: () => void;
|
||||
onGestureEnd?: () => void;
|
||||
@@ -46,22 +48,34 @@ type Props = TransitionPreset & {
|
||||
};
|
||||
headerMode: HeaderMode;
|
||||
headerTransparent?: boolean;
|
||||
floaingHeaderHeight: number;
|
||||
floatingHeaderHeight: number;
|
||||
hasCustomHeader: boolean;
|
||||
};
|
||||
|
||||
export default class StackItem extends React.PureComponent<Props> {
|
||||
private handleOpen = () =>
|
||||
this.props.onOpenRoute({ route: this.props.scene.route });
|
||||
private handleOpen = () => {
|
||||
const { scene, onTransitionEnd, onOpenRoute } = this.props;
|
||||
|
||||
private handleClose = () =>
|
||||
this.props.onCloseRoute({ route: this.props.scene.route });
|
||||
onTransitionEnd && onTransitionEnd({ route: scene.route });
|
||||
onOpenRoute({ route: scene.route });
|
||||
};
|
||||
|
||||
private handleClose = () => {
|
||||
const { scene, onTransitionEnd, onCloseRoute } = this.props;
|
||||
|
||||
onTransitionEnd && onTransitionEnd({ route: scene.route });
|
||||
onCloseRoute({ route: scene.route });
|
||||
};
|
||||
|
||||
private handleTransitionStart = ({ closing }: { closing: boolean }) => {
|
||||
const { index, scene, onTransitionStart, onGoBack } = this.props;
|
||||
|
||||
onTransitionStart &&
|
||||
onTransitionStart({ index: closing ? index - 1 : index }, { index });
|
||||
onTransitionStart({
|
||||
route: scene.route,
|
||||
previous: { index: closing ? index - 1 : index },
|
||||
current: { index },
|
||||
});
|
||||
|
||||
closing && onGoBack({ route: scene.route });
|
||||
};
|
||||
@@ -86,7 +100,7 @@ export default class StackItem extends React.PureComponent<Props> {
|
||||
onGestureCanceled,
|
||||
onGestureEnd,
|
||||
gestureResponseDistance,
|
||||
floaingHeaderHeight,
|
||||
floatingHeaderHeight,
|
||||
hasCustomHeader,
|
||||
getPreviousRoute,
|
||||
headerMode,
|
||||
@@ -126,7 +140,7 @@ export default class StackItem extends React.PureComponent<Props> {
|
||||
pointerEvents="box-none"
|
||||
containerStyle={
|
||||
headerMode === 'float' && !headerTransparent && !hasCustomHeader
|
||||
? { marginTop: floaingHeaderHeight }
|
||||
? { marginTop: floatingHeaderHeight }
|
||||
: null
|
||||
}
|
||||
contentStyle={cardStyle}
|
||||
|
||||
@@ -19,8 +19,8 @@ type Props = {
|
||||
descriptors: Descriptors;
|
||||
navigationConfig: NavigationConfig;
|
||||
onTransitionStart?: (
|
||||
curr: { index: number },
|
||||
prev: { index: number }
|
||||
current: { index: number },
|
||||
previous: { index: number }
|
||||
) => void;
|
||||
onGestureBegin?: () => void;
|
||||
onGestureCanceled?: () => void;
|
||||
|
||||
Reference in New Issue
Block a user