zoukankan      html  css  js  c++  java
  • 一起来学习React-Native之react-navigation基本解析

    前言

      不久前自己也完整开发了一个React-Native项目,对其中的一些知识存在疑惑,再加上项目时间比较紧张,来不及做系统的学习。现在来回顾自己开发当中存在的疑惑点,和大家分享。第一篇是关于路由框架react-navigation,当时其实也没有好好看文档,现在回头看路由设计的确实比较乱,如果没看过文档建议直接去看文档,而后再看此篇文章。主要介绍createStackNavigator,createSwitchNavigator,createBottomTabNavigator,createMaterialTopTabNavigator,这四类路由框架,以及他们的组合使用。

    createStackNavigator

      顾名思义,其实这就是一种基于栈的路由管理方式,栈的特点就是先入后出,最新入栈的界面会显示在最顶部,这也是Android管理Activity的方式,也是React-Native App打开页面最主要的方式。

      

      export function createStackNavigator(
        routeConfigMap: NavigationRouteConfigMap,
        stackConfig?: StackNavigatorConfig
      ): NavigationContainer;

       该方法提供两个参数,一个是NavigationRouteConfigMap,当中存储的一些你声明的组件,他们之间构成了一个单独的路由。还有一个参数是StackNavigatorConfig,它允许你对路由做一个全局的设置,比如说是否显示头部,头部的主题等等。这边建议都不显示头部,更多的时候,页面的头部不尽相同,通过自定的这种形式会对开发更加的友好。需要注意的是,在最新版本的react-navigation当中,必须通过createAppContainer包裹导出。通过创建js文件:AppNavigator.js,一个完整的基于createStackNavigator的例子如下:

    import {
        createStackNavigator,
        createSwitchNavigator,
        createAppContainer,
        createBottomTabNavigator,
        createMaterialTopTabNavigator
    } from 'react-navigation'
    import SplashPage from "../page/Splash/SplashPage";
    import HomePage from "../page/Home/HomePage";
    import Feather from "react-native-vector-icons/Feather"
    import Page1 from "../page/bottom/Page1";
    import Page2 from "../page/bottom/Page2";
    import Page3 from "../page/bottom/Page3";
    import React from "react";
    import Top1 from "../page/top/Top1";
    import Top2 from "../page/top/Top2";
    import Top3 from "../page/top/Top3";
    
    
    const InitNavigator = createStackNavigator({
        SplashPage: {
            screen: SplashPage,
            navigationOptions: {
                header: null
            }
        },
        Page1: {
            screen: Page1,
            navigationOptions: {
                header: null
            }
        },
        Page2: {
            screen: Page2,
            navigationOptions: {
                header: null
            }
        },
        Page3: {
            screen: Page3,
            navigationOptions: {
                header: null
            }
        },
    
    },{
    
    });
    
    export default createAppContainer(InitNavigator);

    这个时候我们只需要修改App.js,就可以完成接入路由这个操作了。

    import React, {Component} from 'react';
    import {Platform, StyleSheet, Text, View, TouchableOpacity} from 'react-native';
    import AppNavigator from "./app/navigation/AppNavigator";
    
    type Props = {};
    export default class App extends Component<Props> {
        render() {
            return (
                <AppNavigator/>
            );
        }
    }

      可以看到,单个js文件中的路由以单个组件的形式提供,可以预见,在项目路由复杂,项目路由多这种情况下react-navigation也一样可以轻松的管理路由。具体的页面代码就不再展示,效果如下:

    createSwitchNavigator

      switch,意思也比较明显,就是选择的意思。也就是说,当你使用这个路由时,内存中只会存在一个页面或者一个路由(多路由情况)。其实,大多数App都有一个欢迎界面,这个界面在App中只会显示一次,如果单单是使用栈的形式,不好控制出栈的操作,实现起来就比较复杂,那么我们的createSwitchNavigator就能派上用场了。当跳转到我们的主路由的时候,欢迎界面也就消失了。来看一下createSwitchNavigator中提供的参数:

      export function createSwitchNavigator(
        routeConfigMap: NavigationRouteConfigMap,
        switchConfig?: SwitchNavigatorConfig
      ): NavigationContainer;

      可以看到和createStackNavigator大同小意,也是一个路由管理集合,和一个可以对界面的总体设置,那么要实现我们上面想要的效果如何去做呢?其实也非常简单,代码如下:

    import {
        createStackNavigator,
        createSwitchNavigator,
        createAppContainer,
        createBottomTabNavigator,
        createMaterialTopTabNavigator
    } from 'react-navigation'
    import SplashPage from "../page/Splash/SplashPage";
    import HomePage from "../page/Home/HomePage";
    import Feather from "react-native-vector-icons/Feather"
    import Page1 from "../page/bottom/Page1";
    import Page2 from "../page/bottom/Page2";
    import Page3 from "../page/bottom/Page3";
    import React from "react";
    import Top1 from "../page/top/Top1";
    import Top2 from "../page/top/Top2";
    import Top3 from "../page/top/Top3";
    
    
    const InitNavigator = createStackNavigator({
        Page1: {
            screen: Page1,
            navigationOptions: {
                header: null
            }
        },
        Page2: {
            screen: Page2,
            navigationOptions: {
                header: null
            }
        },
        Page3: {
            screen: Page3,
            navigationOptions: {
                header: null
            }
        },
    
    },{
    
    });
    
    
    const AppRoot = createSwitchNavigator({
        SplashPage: {
            screen: SplashPage,
            navigationOptions: {
                header: null
            }
        },
        Main: InitNavigator,
    });
    export default createAppContainer(AppRoot);

      那么这个时候,我们的splash界面就不再是跳转到page1了。而是在AppRoot中的Main了

    import BasePage from "../../base/BasePage";
    import {Platform, StyleSheet, Text, View, TouchableOpacity} from 'react-native';
    import React, {Component} from 'react';
    
    export default class SplashPage extends BasePage {
    
    
        render() {
            return (
                <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
                    <TouchableOpacity onPress={() => {
                        this.goNextPage("Main")
                    }}>
                        <Text>Splash</Text>
                    </TouchableOpacity>
                </View>
            );
        }
    }

      现在来看下效果

    createBottomTabNavigator

      如果我们要实现类似微信首页多tab多界面的时候,createBottomTabNavigator就能派上用场了,他通过单个路由管理多个tab,我们来看一下实现的参数:

     

     export function createBottomTabNavigator(
        routeConfigMap: NavigationRouteConfigMap,
        drawConfig?: BottomTabNavigatorConfig
      ): NavigationContainer;

      哎呀,和前面两个一样,也是一个路由管理集合,和一个可以对界面的总体设置。具体设置属性的参数这里不多说,以后的文章会说到,我们把上面提到的两个路由结合起来,实现一个大部分App都有的一个正常路由流程。外部是个createSwitchNavigator做splash和主路由,主路由通过createStackNavigator用栈管理,但是第一个page我们使用createBottomTabNavigator做首页。那么代码如下:

    import {
        createStackNavigator,
        createSwitchNavigator,
        createAppContainer,
        createBottomTabNavigator,
        createMaterialTopTabNavigator
    } from 'react-navigation'
    import SplashPage from "../page/Splash/SplashPage";
    import HomePage from "../page/Home/HomePage";
    import Feather from "react-native-vector-icons/Feather"
    import Page1 from "../page/bottom/Page1";
    import Page2 from "../page/bottom/Page2";
    import Page3 from "../page/bottom/Page3";
    import React from "react";
    import Top1 from "../page/top/Top1";
    import Top2 from "../page/top/Top2";
    import Top3 from "../page/top/Top3";
    
    let hotSelest = <Feather
        name={'activity'}
        size={26}
        color='red'
    />;
    let hotUnSelest = <Feather
        name={'activity'}
        size={26}
    />;
    let pointSelect = <Feather
        name={'thumbs-up'}
        size={26}
        color='red'
    />;
    let pointUnSelect = <Feather
        name={'thumbs-up'}
        size={26}
    />;
    let mineSelect = <Feather
        name={'user'}
        size={26}
        color='red'
    />;
    let mineUnSelect = <Feather
        name={'user'}
        size={26}
    />;
    
    const BottomNavigator = createBottomTabNavigator({
        Page1: {
            screen: Page1,
            navigationOptions: {
                tabBarLabel: '最热',
                tabBarIcon: ({tinColor, focused}) => (focused ? hotSelest : hotUnSelest)
            }
        },
        Page2: {
            screen: Page2,
            navigationOptions: {
                tabBarLabel: '点赞',
                tabBarIcon: ({tinColor, focused}) => (focused ? pointSelect : pointUnSelect)
            }
        },
        Page3: {
            screen: Page3,
            navigationOptions: {
                tabBarLabel: '我的',
                tabBarIcon: ({tinColor, focused}) => (focused ? mineSelect : mineUnSelect)
            }
        },
    }, {
        tabBarOptions: {
            activeTintColor: '#e91e63',
            header: null,
        }
    });
    
    const InitNavigator = createStackNavigator({
        Page1: {
            screen: BottomNavigator,
            navigationOptions: {
                header: null
            }
        },
        Top1: {
            screen: Top1,
            navigationOptions: {
                header: null
            }
        },
        Top2: {
            screen: Top2,
            navigationOptions: {
                header: null
            }
        },
    
    },{
    
    });
    
    const AppRoot = createSwitchNavigator({
        SplashPage: {
            screen: SplashPage,
            navigationOptions: {
                header: null
            }
        },
        Main: InitNavigator,
    });
    export default createAppContainer(AppRoot);

      通过设置lable,icon两个属性,设置图片和文字,这边没有图片,所以使用了一个三方库,有兴趣的可以了解一下。你也可以在,全局的设置当中设置是否显示lable和icon和文字选中颜色等等。首页的第一个界面点击之后会跳转到top界面,效果如下:

    createMaterialTopTabNavigator

      同过实现一个material风格的顶部选择导航,相对于createBottomTabNavigator,有些属性不同。我们来看看实现方法:

    export function createMaterialTopTabNavigator(
        routeConfigMap: NavigationRouteConfigMap,
        drawConfig?: TabNavigatorConfig
      ): NavigationContainer;

    也是大同小异,具体的属性差别实践之后体会更加深刻,我也会在后面介绍,包括一下高级的用法。我们让首页第一个变成materialtop的风格,代码也是非常简单,我们在上面的基础上修改一下:

    import {
        createStackNavigator,
        createSwitchNavigator,
        createAppContainer,
        createBottomTabNavigator,
        createMaterialTopTabNavigator
    } from 'react-navigation'
    import SplashPage from "../page/Splash/SplashPage";
    import HomePage from "../page/Home/HomePage";
    import Feather from "react-native-vector-icons/Feather"
    import Page1 from "../page/bottom/Page1";
    import Page2 from "../page/bottom/Page2";
    import Page3 from "../page/bottom/Page3";
    import React from "react";
    import Top1 from "../page/top/Top1";
    import Top2 from "../page/top/Top2";
    import Top3 from "../page/top/Top3";
    
    
    const TopNavigator= createMaterialTopTabNavigator({
        TopOne:{
            screen:Top1
        },
        TopTwo:{
            screen:Top2
        },
        TopThree:{
            screen:Top3
        },
    });
    
    
    let hotSelest = <Feather
        name={'activity'}
        size={26}
        color='red'
    />;
    let hotUnSelest = <Feather
        name={'activity'}
        size={26}
    />;
    let pointSelect = <Feather
        name={'thumbs-up'}
        size={26}
        color='red'
    />;
    let pointUnSelect = <Feather
        name={'thumbs-up'}
        size={26}
    />;
    let mineSelect = <Feather
        name={'user'}
        size={26}
        color='red'
    />;
    let mineUnSelect = <Feather
        name={'user'}
        size={26}
    />;
    
    const BottomNavigator = createBottomTabNavigator({
        Page1: {
            screen: TopNavigator,
            navigationOptions: {
                tabBarLabel: '最热',
                tabBarIcon: ({tinColor, focused}) => (focused ? hotSelest : hotUnSelest)
            }
        },
        Page2: {
            screen: Page2,
            navigationOptions: {
                tabBarLabel: '点赞',
                tabBarIcon: ({tinColor, focused}) => (focused ? pointSelect : pointUnSelect)
            }
        },
        Page3: {
            screen: Page3,
            navigationOptions: {
                tabBarLabel: '我的',
                tabBarIcon: ({tinColor, focused}) => (focused ? mineSelect : mineUnSelect)
            }
        },
    }, {
        tabBarOptions: {
            activeTintColor: '#e91e63',
            header: null,
        }
    });
    
    const InitNavigator = createStackNavigator({
        Page1: {
            screen: BottomNavigator,
            navigationOptions: {
                header: null
            }
        },
        Top1: {
            screen: Top1,
            navigationOptions: {
                header: null
            }
        },
        Top2: {
            screen: Top2,
            navigationOptions: {
                header: null
            }
        },
    
    },{
    
    });
    const AppRoot = createSwitchNavigator({
        SplashPage: {
            screen: SplashPage,
            navigationOptions: {
                header: null
            }
        },
        Main: InitNavigator,
    });
    export default createAppContainer(AppRoot);

      在createBottomTabNavigator的第一个界面,加入了materialtop的路由,来看看效果:

    总结

     来做一个简单的总结:

     1.这几种路由无非就是两个参数,一个是界面的集合以及全局界面属性的设置,不同的路由属性不同,你也可以在单个界面设置他的属性。

     2.路由的使用需要通过createAppContainer包裹,他以一个组件的形式体现在我们的界面上,这也是新版本加上的,无疑让他更加的灵活。

     3.一个完整的App路由绝对不是单个路由那么简单的,要好好思考App的业务逻辑,设置出专属于你的路由,react-navigation完全能胜任这个工作。

     最后,核心代码都在上面,我就不贴项目连接了。

  • 相关阅读:
    Ural 2040 Palindromes and Super Abilities 2
    BZOJ3676: [Apio2014]回文串
    HDU3068 最长回文
    [USACO06DEC] Milk Patterns
    hdu 6200 mustedge mustedge mustedge(dfs序+树状数组+并查集)
    hdu 4511 小明系列故事——女友的考验(AC自动机+dp)
    hdu 5129 Yong Zheng's Death(AC自动机fail树的应用)
    poj 1991 Turning in Homework(贪心+区间dp)
    hdu 4776 Ants(trie+优先队列)
    hdu 4775 Infinite Go(并查集模拟)
  • 原文地址:https://www.cnblogs.com/lovelyYakir/p/10975033.html
Copyright © 2011-2022 走看看