导航器

此组件提供了一种方式,让应用程序可以呈现一个虚拟的“卡片”堆栈,允许用户以动画方式将这些卡片推入或弹出堆栈。调用者可以控制动画类型和方向。

当呈现新卡片时,导航器会调用 renderScene 方法,允许调用者渲染内容。卡片通过“路由”识别,路由包含一个唯一的 ID 和控制过渡行为的配置参数。

当导航器首次挂载时,堆栈是空的。调用者必须等待挂载完成,然后指定要呈现的路由列表。

React Native 上导航器的当前实现使用了已弃用的“Navigator Experimental”。我们将在不久的将来考虑将此实现迁移到现在推荐的“react-navigation”。一些更高级的接口可能需要更改。这些列在本文的末尾。请谨慎使用这些接口。

安装:npm install reactxp-navigation

类型

// Specifies the behavior when transitioning from one
// card to another within the stack.
enum NavigatorSceneConfigType {
    FloatFromRight,
    FloatFromLeft,
    FloatFromBottom,
    Fade,
    FadeWithSlide
}

// Provides information about a card and how it should
// be presented when pushed onto the stack or popped
// off the stack.
interface NavigatorRoute {
    // Uniquely identifies the card
    routeId: number;

    // Animation parameter
    sceneConfigType: NavigatorSceneConfigType;

    // Optional gesture response distance override;
    // 0 is equivalent to disabling gestures;
    // works only on React Native platforms
    gestureResponseDistance?: number;

    // Optional custom scene config;
    // works only on React Native platforms
    customSceneConfig?: CustomNavigatorSceneConfig;
}

属性

// Style to apply to the card
cardStyle: ViewStyleRuleSet = undefined;

// Called to render the specified scene
renderScene: (route: NavigatorRoute) => JSX.Element = undefined;

// Called when a transition between cards is complete
transitionCompleted: () => void = undefined;

方法

// Returns the current list of routes
getCurrentRoutes(): Types.NavigatorRoute[];

// Replaces the current list of routes with a new list
immediatelyResetRouteStack(
    nextRouteStack: Types.NavigatorRoute[]): void;

// Pops the top route off the stack
pop(): void;

// Pops zero or more routes off the top of the stack until
// the specified route is top-most
popToRoute(route: Types.NavigatorRoute): void;

// Pops all routes off the stack except for the last
// remaining item in the stack
popToTop(): void;

// Push a new route onto the stack
push(route: Types.NavigatorRoute): void;

// Replaces the top-most route with a new route
replace(route: Types.NavigatorRoute): void;

// Replaces an existing route (identified by index) with
// a new route
replaceAtIndex(route: Types.NavigatorRoute, index: number): void;

// Replaces the next-to-top-most route with a new route
replacePrevious(route: Types.NavigatorRoute): void;

示例用法

此示例演示了应用程序如何使用导航器呈现一个两卡片堆栈,允许用户在它们之间导航。为简洁起见,省略了一些细节。有关完整的工作示例,请查看 hello-world 示例应用程序。

enum NavigationRouteId {
    MainPanel,
    SecondPanel
};

class App extends RX.Component<null, null> {
    private _navigator: RX.Navigator;

    componentDidMount() {
        // Now that the app is mounted, specify the initial
        // navigator route.
        this._navigator.immediatelyResetRouteStack([{
            routeId: NavigationRouteId.MainPanel,
            sceneConfigType: RX.Types.NavigatorSceneConfigType.Fade
        }]);
    }

    render() {
        return (
            <RX.Navigator
                ref={ this._onNavigatorRef }
                renderScene={ this._renderScene }
            />
        );
    }

    private _onNavigatorRef = (navigator: RX.Navigator) => {
        // Stash away a reference to the mounted navigator
        this._navigator = navigator;
    }

    private _renderScene = (navigatorRoute: NavigatorRoute) => {
        switch (navigatorRoute.routeId) {
            case NavigationRouteId.MainPanel:
                return (
                    <MainPanel
                        onPressNavigate={ this._onPressNavigate }
                    />
                );

            case NavigationRouteId.SecondPanel:
                return (
                    <SecondPanel
                        onNavigateBack={ this._onPressBack }
                    />
                );
        }

        return null;
    }

    // Called when the user presses a button on the MainPanel
    // to navigate to the SecondPanel.
    private _onPressNavigate = () => {
        this._navigator.push({
            routeId: NavigationRouteId.SecondPanel,
            sceneConfigType:
                RX.Types.NavigatorSceneConfigType.FloatFromRight,
            customSceneConfig: {
                hideShadow: true
            }
        });
    }

    // Called when the user presses a back button on the
    // SecondPanel to navigate back to the MainPanel.
    private _onPressBack = () => {
        this._navigator.pop();
    }
}

实验性类型

这些类型仅适用于 React Native 平台,它们目前依赖于即将弃用的“Experimental Navigator”。这些类型中的部分或全部可能在不久的将来被弃用,因此请谨慎使用。

// Additional options that affect card transitions
type CustomNavigatorSceneConfig = {
  // Optional transition styles
  transitionStyle?: (sceneIndex: number,
    sceneDimensions: Dimensions) =>
    NavigationTransitionStyleConfig;

  // Optional overrides for duration, easing, and timing
  transitionSpec?: NavigationTransitionSpec;

  // Optional cardStyle override
  cardStyle?: ViewStyleRuleSet;

  // Optionally hide drop shadow
  hideShadow?: boolean;

  // Optionally flip the visual order of the last two scenes
  presentBelowPrevious?: boolean;
};

// Parameters to control transition animations
type NavigationTransitionSpec = {
    duration?: number;
    easing?: Animated.EasingFunction;
};

// Parameters to control transition appearance
type NavigationTransitionStyleConfig = {
  // By default, input range is defined as [index - 1, index, index + 1];
  // Input and output ranges must contain the same number of elements
  inputRange?: number[];
  opacityOutput: number | number[];
  scaleOutput: number | number[];
  translateXOutput: number | number[];
  translateYOutput: number | number[];
};

实验性属性

这些属性仅适用于 React Native 平台,它们目前依赖于即将弃用的“Experimental Navigator”。这些属性中的部分或全部可能在不久的将来被弃用,因此请谨慎使用。

// Called after the user swipes back in the stack and the transition
// is complete
navigateBackCompleted: () => void;

// Called when a transition begins; works only
// on native
transitionStarted: (progress?: RX.AnimatedValue,
    toRouteId?: string, fromRouteId?: string,
    toIndex?: number, fromIndex?: number) => void = undefined;