import React from 'react';
import createNavigationContainer from '../createNavigationContainer';
import createNavigator from './createNavigator';
import CardStackTransitioner from '../views/CardStack/CardStackTransitioner';
import StackRouter from '../routers/StackRouter';
import NavigationActions from '../NavigationActions';
// A stack navigators props are the intersection between
// the base navigator props (navgiation, screenProps, etc)
// and the view's props
/**
* HOC,用于创建一个栈式导航器
* 1.一个栈式导航器首先是一个 Navigator
* 2.一个栈式导航器还是一个 NavigationContainer
* 3.一个栈式导航器内部使用了一个 CardStackTransitioner 组件来渲染屏幕/场景组件
* 3.1 CardStackTransitioner 将所要渲染的每个屏幕/场景组件组织的像一个卡片 Card,所有的这
* 些卡片使用栈方式管理,参考 CardStack
* 3.2 CardStackTransitioner 同时也负责每个卡片切换时的动作过渡效果
* 3.3 CardStackTransitioner 不负责路由状态的管理,路由状态的管理由绑在导航器上的
* StackRouter router来负责
* 4.一个栈式导航器内部创建了一个 StackRouter router 来管理路由状态,并将其添加到了内部
* 使用的 CardStackTransitioner 组件上
*
* * @param routeConfigMap 路由配置参数
* @param stackConfig 其它路由器设置参数
* @returns {NavigationContainer}
*/
export default (routeConfigMap, stackConfig = {}) => {
// 从 stackConfig 中获取各个参数项
const {
initialRouteKey,//初始路由的key
initialRouteName,// 初始路由的名称
initialRouteParams, // 初始路由的参数
paths, // 每个路由的路径定义
// 屏幕头部模式:float(独立于屏幕组件浮动),screen(嵌在屏幕顶部跟随屏幕),none(关闭头部)
headerMode,
headerTransitionPreset,
mode, // 屏幕模式:card(卡片模式),modal(模态)
cardStyle,
transitionConfig,//屏幕切换过渡参数设置
onTransitionStart, // 屏幕切换过渡动画开始回调
onTransitionEnd, // 屏幕切换过渡动画结束回调
navigationOptions, // 导航选项参数
} = stackConfig;
// 构造栈式路由器要使用的参数
const stackRouterConfig = {
initialRouteKey,
initialRouteName,
initialRouteParams,
paths,
navigationOptions,
};
// 创建栈式路由器
const router = StackRouter(routeConfigMap, stackRouterConfig);
// 创建导航器组件,使用 CardStackTransitioner 做为其所渲染的View,
// 而 CardStackTransitioner 最终会把各个路由使用卡片栈的方式管理和渲染(CardStack,Card)
// CardStackTransitioner 同时也处理屏幕切换时的动画过渡以及相应的动画事件回调
// Create a navigator with CardStackTransitioner as the view
const navigator = createNavigator(router, routeConfigMap, stackConfig)(
props => (
<CardStackTransitioner
{...props}
headerMode={headerMode}
headerTransitionPreset={headerTransitionPreset}
mode={mode}
cardStyle={cardStyle}
transitionConfig={transitionConfig}
onTransitionStart={onTransitionStart}
onTransitionEnd={(lastTransition, transition) => {
// 注意,这里动画结束时并不是直接调用外部指定的回调 onTransitionEnd,
// 而是先向路由器 router 派送一个事件 completeTransition ,用于结束屏幕
// 过渡状态:主要是把路由器中路由状态的是否在屏幕过渡中标记 isTransitioning
// 修改为 false,(isTransitioning 设置为 true 是在用户交互时触发的
// navigate/push/pop/back 等动作的处理逻辑中计算出来并设置的)
const {state, dispatch} = props.navigation;
dispatch(NavigationActions.completeTransition({key: state.key}));
// 现在屏幕切换过渡结束了(相关的状态数据已经修改+ 过渡动画已经完成),
// 现在调用外部指定的动画结束回调函数 onTransitionEnd (如果指定了的话)
onTransitionEnd && onTransitionEnd(lastTransition, transition);
}}
/>
)
);
// 为导航器做增强,使其具有 navigation 属性,并在导航状态
// 没有从上面传入时管理导航状态,从而使其可以作为顶层组件使用
return createNavigationContainer(navigator);
};
React Navigation源代码阅读 : navigators/StackNavigator.js
最新推荐文章于 2022-10-05 00:34:56 发布