美文网首页
react-navigation2.0版之Tab导航

react-navigation2.0版之Tab导航

作者: 既然可以颠覆何必循规蹈矩 | 来源:发表于2018-06-30 16:11 被阅读0次

    本文章的版本是react-navigation 2.5.5
    一般来说构建app有两种思路:
    方法1:如果我的App 有几个 tab 就需要用 createStackNavigator建立几个stack,然后用一个createBottomTabNavigator包裹刚刚创建的几个stack。类似于ios原生
    方法2:反过来用stack包裹一个tab和好多screen(单独的页面)
    下面分别说说这两种构建:

    C4451C7A-7D11-4B8F-B68E-31EC851FBB7E.png
    //首页     详情页
    const HomeStack = createStackNavigator({
      Home: HomeScreen,
      Details: DetailsScreen,
    });
    
    //我的 我的设置
    const MeStack = createStackNavigator({
      Me: MeScreen,
      Setting: SettingScreen,
      // Details: DetailsScreen 跨tab跳转需要额外注册
    });
    

    然后通过 createBottomTabNavigator把stack包裹

    export default createBottomTabNavigator(
    {
      Home: HomeStack,
      Me: MeStack,
    });
    
    

    这种写法有个缺点就是子页面也会存在下面的tab 而且需要在每个stack 判断一下。2.0的处理方法如下:

    HomeStack.navigationOptions = ({ navigation }) => {
      let tabBarVisible = true;
      if (navigation.state.index > 0) {
        tabBarVisible = false;
      }
      return {
        tabBarVisible,
      };
    };
    

    如果需要夸tab跳转就额外注册,比如我要从Me 里面跳转到 Details 则需要在 MeStack 里面 设置 Details: DetailsScreen

    或者你采用另外一个布局方式 stack包裹tab

    const TabOptions = (tabBarTitle, tabBarIconName) => {
        const title = tabBarTitle;
        const tabBarIcon = (({tintColor,focused})=> {
            const color = focused ? CS.THEME11 : CS.COLOR4;
            if(title){
                return(
                    <Icon name={tabBarIconName} size={title?FS.ICON_B:40} color={color}/>
                )
            }else {
                return(
                    <FontAwesome name={tabBarIconName} size={44} color={CS.THEME11}/>
                )
            }
    
        });
        const tabBarVisible = true;
        return { title, tabBarIcon, tabBarVisible };
    };
    
    const MyTab = createBottomTabNavigator({
        ScreenHome: {
            screen: ScreenHome,
            navigationOptions: ()=> TabOptions('找房', 'oneIcon|icon_search'),
        },
    
        ScreenGroup: {
            screen: ScreenGroup,
            navigationOptions: ()=> TabOptions('圈子', 'oneIcon|icon_fenxiaoquan_light'),
        },
    
        ScreenAdd: { screen: ScreenAdd,
            // 这里我实现了隐藏单个文字的tab  达到了类似微博的效果我是修改了源码
            navigationOptions: ()=> TabOptions('','plus-circle'),
        },
    
        ScreenMessage: {
            screen: ScreenMessage,
            navigationOptions: ()=> TabOptions('消息', 'oneIcon|icon__xiaoxi'),
        },
    
        ScreenMe: {
            screen: ScreenMe,
            navigationOptions: ()=> TabOptions('我的', 'oneIcon|icon_me'),
        },
    })
    
    const AppStack = createStackNavigator({
            MyTab : MyTab,
            Detail : Detail
    })
    

    但是这种方法也有一个问题 就是tab页面的头不好隐藏,1.0版本的方式不适用了,需要做如下处理

    MyTab.navigationOptions = ({ navigation }) => {
        let { routeName } = navigation.state.routes[navigation.state.index];
        if(routeName=='ScreenHome'||routeName=='ScreenGroup'||routeName=='ScreenMe'){
            return {
                header:null,
            };
        }else if(routeName=='ScreenAdd'){
            return {
                headerTitle:'发布',
            };
        }else if(routeName=='ScreenMessage'){
            return {
                headerTitle:'消息',
            };
        }
    };
    

    需要隐藏单个文字的话修改源码如下:
    自己额外加了一个判断,文件路径 node_modules/react-navigation-tabs/dist/views 30多行左右

    if (typeof label === 'string') {
          if(label==''){
              return null;
          }else {
              return <Animated.Text numberOfLines={1} style={[styles.label, { color: tintColor }, showIcon && this._shouldUseHorizontalLabels() ? styles.labelBeside : styles.labelBeneath, styles.labelBeneath, labelStyle]} allowFontScaling={allowFontScaling}>
                  {label}
              </Animated.Text>;
          }
        }
    

    那么我们的登录流程和怎么和tab结合呢

    这个时候我们就要用到createSwitchNavigator.说白了createSwitchNavigator里面的只能显示一个,这个就相当于之前的reset()方法.不处理回退操作,切换时将路由重置为默认状态. 他跳转(navigate())后其余的页面都销毁了

    // 这里演示的是第二种方式
    const AppStack = createStackNavigator({
           MyTab : MyTab,
           Detail : Detail
    })
    const LoginStack = createStackNavigator({
       Login : Login,
       Register : Register,
    });
    
    export defaul const AppNavigator = createSwitchNavigator({
       Splash : Splash,  // 这是引导页
       LoginStack : LoginStack,  // 这里包含登录前的所有页面,比如注册,登录 ,忘记密码 等
       App : AppStack, // 这里面包含所有登录后的页面
    });
    
    

    相关文章

      网友评论

          本文标题:react-navigation2.0版之Tab导航

          本文链接:https://www.haomeiwen.com/subject/uultuftx.html