入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

React Native导航react-navigation经验浅谈

创建时间:2017-06-18 投稿人: 浏览次数:3809

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"
  },
});
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。