React Native导航react-navigation经验浅谈

react-navigation是一个很好用的导航组件,官方文档也很详细:https://reactnavigation.org/docs/intro/ 虽然用的很爽,但是在使用过程中还是遇到了一些问题,最大的问题是如何进行项目中的导航嵌套。

首先介绍一下react-navigation中导航的三种形式:
1.StackNavigator 页面堆栈导航
2.TabNavigator 底部(或顶部)标签导航
3.DrawerNavigator 侧边栏滑动导航

关于这三种导航具体是什么样子的,可以自己试试或者看官方网站中他们在Expo上有个演示的app,很详细。

在项目中遇到的问题是如何组织嵌套这三种导航,需要实现的导航效果是有一个左边滑动导航,一个底部的4个标签的导航,然后在页面中点击按钮会转到新的堆栈导航,效果如图

但是构建项目的时候如何组织嵌套这三种代码,经过了很多次不同的尝试,参考官方github的issue:https://github.com/react-community/react-navigation/issues/1849
有人推荐可以这样嵌套

StackNavigator
- TabNavigator
- DrawerNavigator

( 官方文档中关于DrawerNavigator最后有这样一句话:
Please bear in mind that if you nest the DrawerNavigation, the drawer will show below the parent navigation. 如果按上面那样实现嵌套的话,侧边栏的滑动导航高度不会占全屏,StackNavigator的顶栏会占去一部分高度,drawer是在stack下面的)

然后还举了个Android Twitter的例子:

StackNavigator
- Login Screen
- Home Screen
  + TabNavigator
    - Feed
    - Search
    - Notifications
    - Messages
- DrawerNavigator
  (custom made the content & drawer list to call navigation.navigate)
- Profile
- Highlights
- Moments
- Lists
- Connect
...etc
```

经过多次尝试,我的嵌套导航是这样的

DrawerNavigator
    - StackNavigator
        - TabNavigator

即Drawer是根导航,stack嵌套在其下,然后tab又嵌套在stack下。
这样做有一个小小的奇怪的地方,就是Drawer中会显示三个导航,如图中有“我的”“登录”,原本在“我的”上面还有一个标签,用来回到主页,但是看上去很奇怪就没有设置标签文字,但是应该是有办法不显示的,我一开始想的是直接改动node_modules中引用的源代码判断第一条不显示。。。后来想想不对啊,,,npm install的时候岂不是,,,然后没有想到解决办法只是把标签内的文字设成空的。

为方便参考,下面是我的导航组件的源代码

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  Button,
  ScrollView,
  View
} from 'react-native';
import { StackNavigator, TabNavigator, DrawerNavigator } from 'react-navigation';
import { DrawerItems } from 'react-navigation';

// 实现自定义IconFont更好用,取消引入Ionicons
// import Ionicons from 'react-native-vector-icons/Ionicons';
import { IconFont } from './IconFont';

// 首页
import { HomeScreen } from '../views/HomeScreen';
// 打卡页面
import { CardScreen } from '../views/CardScreen';
// 清单页面
import { ListScreen } from '../views/ListScreen';
// 记账页面
import { AccountScreen } from '../views/AccountScreen';
// 我的页面
import { MyScreen } from '../views/MyScreen';
// 登录页面
import { LoginScreen } from '../views/LoginScreen';

// 添加卡片
import { AddCard } from '../views/Card/AddCard';
// 添加清单
import { AddList } from '../views/List/AddList';
// 清单列表
import { ListContent } from '../views/List/ListContent';
// 清单详情
import { ListDetail } from '../views/List/ListDetail';

/*
 * stackNavigator
 * 四个主页面
*/
const stackOption = {
    navigationOptions: {
      headerTintColor: '#fff',
      headerStyle: {
        backgroundColor: '#6495ED',//矢车菊蓝
      }
  }
}

// 我的导航
const MyStack = StackNavigator({
    MyScreen: {
      screen: MyScreen,
      navigationOptions: {
        title: '我的',
        tabBarLabel: '我的',
        tabBarIcon: ({ tintColor, focused }) => (
          <Ionicons 
            name={'md-create'} 
            size={28} 
            style={{ color: tintColor }} 
          />
        ),
      },
    },
},stackOption);

/*
 * tabNavigator
 * 
*/
const AppTabNav = TabNavigator({
    Home: { 
      screen: HomeScreen,
      navigationOptions: {
        title: '梦想助手',
        tabBarLabel: '首页',
        tabBarIcon: ({ tintColor, focused }) => (
          <IconFont
            font="&#xe7d8;"
            style={{ color: tintColor, fontSize: 26 }}
          />
        ),
      },
    },
    Card: { 
      screen: CardScreen,
      navigationOptions: ({ navigation }) => ({
        title: '梦想打卡',
        tabBarLabel: '打卡',
        tabBarIcon: ({ tintColor, focused }) => (
          <IconFont
            font="&#xe751;"
            style={{ color: tintColor, fontSize: 26 }}
          />
        ),
        headerRight: <IconFont 
                        font="&#xe6da;" 
                        style={{color: '#fff', marginRight: 15, fontSize: 30}} 
                        onPress={() => navigation.navigate('AddCard') } 
                     />,
      }),
    },
    List: { 
      screen: ListScreen,
      navigationOptions: ({ navigation }) => ({
        title: '梦想清单',
        tabBarLabel: '清单',
        tabBarIcon: ({ tintColor, focused }) => (
          <IconFont
            font="&#xe65b;"
            style={{ color: tintColor, fontSize: 26 }}
          />
        ),
        headerRight: <IconFont 
                        font="&#xe6da;" 
                        style={{color: '#fff', marginRight: 15, fontSize: 30}} 
                        onPress={() => navigation.navigate('AddList') } 
                     />,
      }),
    },
    Account: { 
      screen: AccountScreen,
      navigationOptions: {
        title: '记账',
        tabBarLabel: '记账',
        tabBarIcon: ({ tintColor, focused }) => (
          <IconFont
            font="&#xe614;"
            style={{ color: tintColor, fontSize: 26 }}
          />
        ),
      },
    }
}, {
    initialRouteName: 'Home',
    tabBarPosition: 'bottom',
    tabBarOptions: {
      showIcon: true,
      showLabel: false,

      activeTintColor: '#6495ED',
      inactiveTintColor: '#666',

      indicatorStyle: {
        backgroundColor: '#fff',
      },
      style: {
        backgroundColor: '#fff',
        borderTopWidth: 1,
        borderTopColor: '#f0f0f0',
      }
    }
});



const AppStack = StackNavigator({
    Home: {
      screen: AppTabNav,
    },
    AddCard: { 
      screen: AddCard,
      navigationOptions: {
          title: '添加卡片'
      }
    },
    AddList: {
      screen: AddList,
      navigationOptions: {
          title: '添加清单'
      }
    },
    ListContent: {
      screen: ListContent,
      navigationOptions: {
          title: '列表标题'
      }
    },
    ListDetail: {
      screen: ListDetail,
      navigationOptions: {
          title: '列表标题',
          headerRight: <IconFont 
                        font="&#xe645;" 
                        style={{color: '#fff', marginRight: 15, fontSize: 28}} 
                        onPress={() => alert("ok") } 
                     />,
      }
    },
}, stackOption);




/*
 * drawerNavigator
 * 
*/
// 自定义侧边导航栏
const DrawerContent = (props) => {
  return(
    <View style={styles.container}>
      <View style={styles.header}>
        <Text style={styles.welcome}>欢迎</Text>
      </View>
      <DrawerItems {...props} />
    </View>
  )
};

export const AppNav = DrawerNavigator({
  App: {
      screen: AppStack,
      navigationOptions: {
        title: '',
        tabBarLabel: '',
      },
  },
  MyScreen: {
    screen: MyStack,
  },
  LoginScreen: {
      screen: LoginScreen
  },
},{
  contentComponent: props => <ScrollView><DrawerContent {...props} /></ScrollView>
});


const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  header: {
    height: 200,
    width: '100%'
  },
  welcome: {
    fontSize: 20,
    height: 80,
    textAlign: 'center',
    textAlignVertical: 'center'
  },
});
  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值