zoukankan      html  css  js  c++  java
  • React Native——react-navigation的使用

    在 React Native 中,官方已经推荐使用 react-navigation 来实现各个界面的跳转和不同板块的切换。 react-navigation 主要包括三个组件:

    • StackNavigator 导航组件
    • TabNavigator 切换组件
    • DrawerNavigator 抽屉组件

    StackNavigator 用于实现各个页面之间的跳转, TabNavigator 用来实现同一个页面上不同界面的切换, DrawerNavigator 可以实现侧滑的抽屉效果。

    StackNavigator

    StackNavigator 组件采用堆栈式的页面导航来实现各个界面跳转。它的构造函数:

    StackNavigator(RouteConfigs, StackNavigatorConfig)

    有 RouteConfigs 和 StackNavigatorConfig 两个参数。

    RouteConfigs

    RouteConfigs 参数表示各个页面路由配置,类似于android原生开发中的 AndroidManifest.xml ,它是让导航器知道需要导航的路由对应的页面。

    const RouteConfigs = {
        Home: {
            screen: HomePage,
            navigationOptions: ({navigation}) => ({
                title: '首页',
            }),
        },
        Find: {
            screen: FindPage,
            navigationOptions: ({navigation}) => ({
                title: '发现',
            }),
        },
        Mine: {
            screen: MinePage,
            navigationOptions: ({navigation}) => ({
                title: '我的',
            }),
        },
    };

    这里给导航器配置了三个页面, Home 、 Find 、 Mine 为路由名称, screen 属性值 HomePage 、 FindPage 、 MinePage 为对应路由的页面。

    navigationOptions 为对应路由页面的配置选项:

    title - 可以作为头部标题 headerTitle ,或者Tab标题 tabBarLabel
    header - 自定义的头部组件,使用该属性后系统的头部组件会消失
    headerTitle - 头部的标题,即页面的标题
    headerBackTitle - 返回标题,默认为 title
    headerTruncatedBackTitle - 返回标题不能显示时(比如返回标题太长了)显示此标题,默认为 “Back”
    headerRight - 头部右边组件
    headerLeft - 头部左边组件
    headerStyle - 头部组件的样式
    headerTitleStyle - 头部标题的样式
    headerBackTitleStyle - 头部返回标题的样式
    headerTintColor - 头部颜色
    headerPressColorAndroid - Android 5.0 以上MD风格的波纹颜色
    gesturesEnabled - 否能侧滑返回, iOS 默认 true , Android 默认 false

    StackNavigatorConfig

    StackNavigatorConfig 参数表示导航器的配置,包括导航器的初始页面、各个页面之间导航的动画、页面的配置选项等等:

    const StackNavigatorConfig = {
        initialRouteName: 'Home',
        initialRouteParams: {initPara: '初始页面参数'},
        navigationOptions: {
            title: '标题',
            headerTitleStyle: {fontSize: 18, color: '#666666'},
            headerStyle: {height: 48, backgroundColor: '#fff'},
        },
        paths: 'page/main',
        mode: 'card',
        headerMode: 'screen',
        cardStyle: {backgroundColor: "#ffffff"},
        transitionConfig: (() => ({
            screenInterpolator: CardStackStyleInterpolator.forHorizontal,
        })),
        onTransitionStart: (() => {
            console.log('页面跳转动画开始');
        }),
        onTransitionEnd: (() => {
            console.log('页面跳转动画结束');
        }),
    };
    initialRouteName - 导航器组件中初始显示页面的路由名称,如果不设置,则默认第一个路由页面为初始显示页面
    initialRouteParams - 给初始路由的参数,在初始显示的页面中可以通过 this.props.navigation.state.params 来获取
    navigationOptions - 路由页面的配置选项,它会被 RouteConfigs 参数中的 navigationOptions 的对应属性覆盖。
    paths - 路由中设置的路径的覆盖映射配置
    mode - 页面跳转方式,有 card 和 modal 两种,默认为 card :
    card - 原生系统默认的的跳转
    modal - 只针对iOS平台,模态跳转
    headerMode - 页面跳转时,头部的动画模式,有 float 、 screen 、 none 三种:
    float - 渐变,类似iOS的原生效果
    screen - 标题与屏幕一起淡入淡出
    none - 没有动画
    cardStyle - 为各个页面设置统一的样式,比如背景色,字体大小等
    transitionConfig - 配置页面跳转的动画,覆盖默认的动画效果
    onTransitionStart - 页面跳转动画即将开始时调用
    onTransitionEnd - 页面跳转动画一旦完成会马上调用

    页面的配置选项 navigationOptions 通常还可以在对应页面中去静态配置,比如在 HomePage 页面中:

    export default class HomePage extends Component {
    
        // 配置页面导航选项
        static navigationOptions = ({navigation}) => ({
            title: 'HOME',
            titleStyle: {color: '#ff00ff'},
            headerStyle:{backgroundColor:'#000000'}
        });
    
        render() {
            return (
                <View></View>
            )
        };
    }

    同样地,在页面里面采用静态的方式配置 navigationOptions 中的属性,会覆盖 StackNavigator 构造函数中两个参数 RouteConfigs 和 StackNavigatorConfig 配置的 navigationOptions 里面的对应属性。 navigationOptions 中属性的优先级是:

    页面中静态配置 > RouteConfigs > StackNavigatorConfig

    有了 RouteConfigs 和 StackNavigatorConfig 两个参数,就可以构造出一个导航器组件 StackNavigator ,直接引用该组件:

    const Navigator = StackNavigator(RouteConfigs, StackNavigatorConfig);
    
    export default class MainComponent extends Component {
        render() {
            return (
                <Navigator/>
            )
        };
    }

    已经配置好导航器以及对应的路由页面了,但是要完成页面之间的跳转,还需要 navigation

    navigation

    在导航器中的每一个页面,都有 navigation 属性,该属性有以下几个属性/方法:

    navigate - 跳转到其他页面
    state - 当前页面导航器的状态
    setParams - 更改路由的参数
    goBack - 返回
    dispatch - 发送一个action

    navigete

    调用这个方法可以跳转到导航器中的其他页面,此方法有三个参数:

    — routeName 导航器中配置的路由名称
    
    — params 传递参数到下一个页面
    
    — action action
    
    比如: this.props.navigation.navigate('Find', {param: 'i am the param'});

    state

    state 里面包含有传递过来的参数 params 、 key 、路由名称 routeName ,打印log可以看得到:

    { 
      params: { param: 'i am the param' },
      key: 'id-1500546317301-1',
      routeName: 'Mine' 
    }

    setParams

    更改当前页面路由的参数,比如可以用来更新头部的按钮或者标题。

    componentDidMount() {
        this.props.navigation.setParams({param:'i am the new param'})
    }

    goBack

    回退,可以不传,也可以传参数,还可以传 null 。

    this.props.navigation.goBack();       // 回退到上一个页面
    this.props.navigation.goBack(null);   // 回退到任意一个页面
    this.props.navigation.goBack('Home'); // 回退到Home页面

    TabNavigator

    TabNavigator ,即是Tab选项卡,类似于原生 android 中的 TabLayout ,它的构造函数:

    TabNavigator(RouteConfigs, TabNavigatorConfig)

    api和 StackNavigator 类似,参数 RouteConfigs 是路由配置,参数 TabNavigatorConfig是Tab选项卡配置。

    RouteConfigs

    路由配置和 StackNavigator 中是一样的,配置路由以及对应的 screen 页面, navigationOptions 为对应路由页面的配置选项:

    title - Tab标题,可用作 headerTitle 和 tabBarLabel 回退标题
    tabBarVisible - Tab的是否可见,没有设置的话默认为 true
    tabBarIcon - Tab的icon组件,可以根据 {focused: boolean, tintColor: string} 方法来返回一个icon组件
    tabBarLabel - Tab中显示的标题字符串或者组件,也可以根据 { focused: boolean, tintColor: string } 方法返回一个组件

    TabNavigatorConfig

    tabBarComponent - Tab选项卡组件,有 TabBarBottom 和 TabBarTop 两个值,在iOS中默认为 TabBarBottom ,在Android中默认为 TabBarTop 。
    TabBarTop - 在页面的顶部
    TabBarBottom - 在页面的底部
    tabBarPosition - Tab选项卡的位置,有 top 或 bottom 两个值
    swipeEnabled - 是否可以滑动切换Tab选项卡
    animationEnabled - 点击Tab选项卡切换界面是否需要动画
    lazy - 是否懒加载页面
    initialRouteName - 初始显示的Tab对应的页面路由名称
    order - 用路由名称数组来表示Tab选项卡的顺序,默认为路由配置顺序
    paths - 路径配置
    backBehavior - androd点击返回键时的处理,有 initialRoute 和 none 两个值
    initailRoute - 返回初始界面
    none - 退出
    tabBarOptions - Tab配置属性,用在 TabBarTop 和 TabBarBottom 时有些属性不一致:
    用于 TabBarTop 时:
    activeTintColor - 选中的文字颜色
    inactiveTintColor - 未选中的文字颜色
    showIcon - 是否显示图标,默认显示
    showLabel - 是否显示标签,默认显示
    upperCaseLabel - 是否使用大写字母,默认使用
    pressColor - android 5.0以上的MD风格波纹颜色
    pressOpacity - android 5.0以下或者iOS按下的透明度
    scrollEnabled - 是否可以滚动
    tabStyle - 单个Tab的样式
    indicatorStyle - 指示器的样式
    labelStyle - 标签的样式
    iconStyle - icon的样式
    style - 整个TabBar的样式
    用于 TabBarBottom 时:
    activeTintColor - 选中Tab的文字颜色
    activeBackgroundColor - 选中Tab的背景颜色
    inactiveTintColor - 未选中Tab的的文字颜色
    inactiveBackgroundColor - 未选中Tab的背景颜色
    showLabel - 是否显示标题,默认显示
    style - 整个TabBar的样式
    labelStyle - 标签的样式
    tabStyle - 单个Tab的样式

    底部Tab导航示例

    import React, {Component} from 'react';
    import {StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";
    import HomeScreen from "./index18/HomeScreen";
    import NearByScreen from "./index18/NearByScreen";
    import MineScreen from "./index18/MineScreen";
    import TabBarItem from "./index18/TabBarItem";
    export default class MainComponent extends Component {
        render() {
            return (
                <Navigator/>
            );
        }
    }
    
    const TabRouteConfigs = {
        Home: {
            screen: HomeScreen,
            navigationOptions: ({navigation}) => ({
                tabBarLabel: '首页',
                tabBarIcon: ({focused, tintColor}) => (
                    <TabBarItem
                        tintColor={tintColor}
                        focused={focused}
                        normalImage={require('./img/tabbar/pfb_tabbar_homepage_2x.png')}
                        selectedImage={require('./img/tabbar/pfb_tabbar_homepage_selected_2x.png')}
                    />
                ),
            }),
        },
        NearBy: {
            screen: NearByScreen,
            navigationOptions: {
                tabBarLabel: '附近',
                tabBarIcon: ({focused, tintColor}) => (
                    <TabBarItem
                        tintColor={tintColor}
                        focused={focused}
                        normalImage={require('./img/tabbar/pfb_tabbar_merchant_2x.png')}
                        selectedImage={require('./img/tabbar/pfb_tabbar_merchant_selected_2x.png')}
                    />
                ),
            },
        }
        ,
        Mine: {
            screen: MineScreen,
            navigationOptions: {
                tabBarLabel: '我的',
                tabBarIcon: ({focused, tintColor}) => (
                    <TabBarItem
                        tintColor={tintColor}
                        focused={focused}
                        normalImage={require('./img/tabbar/pfb_tabbar_mine_2x.png')}
                        selectedImage={require('./img/tabbar/pfb_tabbar_mine_selected_2x.png')}
                    />
                ),
            },
        }
    };
    const TabNavigatorConfigs = {
        initialRouteName: 'Home',
        tabBarComponent: TabBarBottom,
        tabBarPosition: 'bottom',
        lazy: true,
    };
    const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
    const StackRouteConfigs = {
        Tab: {
            screen: Tab,
        }
    };
    const StackNavigatorConfigs = {
        initialRouteName: 'Tab',
        navigationOptions: {
            title: '标题',
            headerStyle: {backgroundColor: '#5da8ff'},
            headerTitleStyle: {color: '#333333'},
        }
    };
    const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

    顶部Tab选项卡示例

    import React, {Component} from "react";
    import {StackNavigator, TabBarTop, TabNavigator} from "react-navigation";
    import HomeScreen from "./index18/HomeScreen";
    import NearByScreen from "./index18/NearByScreen";
    import MineScreen from "./index18/MineScreen";
    export default class MainComponent extends Component {
        render() {
            return (
                <Navigator/>
            );
        }
    }
    
    const TabRouteConfigs = {
        Home: {
            screen: HomeScreen,
            navigationOptions: ({navigation}) => ({
                tabBarLabel: '首页',
            }),
        },
        NearBy: {
            screen: NearByScreen,
            navigationOptions: {
                tabBarLabel: '附近',
            },
        }
        ,
        Mine: {
            screen: MineScreen,
            navigationOptions: {
                tabBarLabel: '我的',
            },
        }
    };
    const TabNavigatorConfigs = {
        initialRouteName: 'Home',
        tabBarComponent: TabBarTop,
        tabBarPosition: 'top',
        lazy: true,
        tabBarOptions: {}
    };
    const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
    const StackRouteConfigs = {
        Tab: {
            screen: Tab,
        }
    };
    const StackNavigatorConfigs = {
        initialRouteName: 'Tab',
        navigationOptions: {
            title: '标题',
            headerStyle: {backgroundColor: '#5da8ff'},
            headerTitleStyle: {color: '#333333'},
        }
    };
    const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

    DrawerNavigator

    在原生Android MD 风格里面很多app都会采用侧滑抽屉来做主页面的导航,利用 DrawerNavigator 在RN中可以很方便来实现抽屉导航.

    DrawerNavigator(RouteConfigs, DrawerNavigatorConfig)

    和 DrawerNavigator 的构造函数一样,参数配置也类似。

    RouteConfigs

    抽屉导航的路由配置 RouteConfigs ,和 TabNavigator 的路由配置完全一样, screen 配置对应路由页面, navigationOptions 为对应页面的抽屉配置选项:

    • title - 抽屉标题,和 headerTitle 、 drawerLabel 一样
    • drawerLabel - 标签字符串,或者自定义组件, 可以根据 { focused: boolean, tintColor: string } 函数来返回一个自定义组件作为标签
    • drawerIcon - 抽屉icon,可以根据 { focused: boolean, tintColor: string } 函数来返回一个自定义组件作为icon

    DrawerNavigatorConfig

    抽屉配置项属性:

    drawerWidth - 抽屉宽度,可以使用Dimensions获取屏幕的宽度,动态计算
    drawerPosition - 抽屉位置,可以是 left 或者 right
    contentComponent - 抽屉内容组件,可以自定义侧滑抽屉中的所有内容,默认为 DrawerItems
    contentOptions - 用来配置抽屉内容的属性。当用来配置 DrawerItems 是配置属性选项:
    items - 抽屉栏目的路由名称数组,可以被修改
    activeItemKey - 当前选中页面的key id
    activeTintColor - 选中条目状态的文字颜色
    activeBackgroundColor - 选中条目的背景色
    inactiveTintColor - 未选中条目状态的文字颜色
    inactiveBackgroundColor - 未选中条目的背景色
    onItemPress(route) - 条目按下时会调用此方法
    style - 抽屉内容的样式
    labelStyle - 抽屉的条目标题/标签样式
    initialRouteName - 初始化展示的页面路由名称
    order - 抽屉导航栏目顺序,用路由名称数组表示
    paths - 路径
    backBehavior - androd点击返回键时的处理,有initialRoute和none两个值, initailRoute:返回初始界面, none :退出

    抽屉导航示例

    import React, {Component} from 'react';
    import {DrawerNavigator, StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";
    import HomeScreen from "./index18/HomeScreen";
    import NearByScreen from "./index18/NearByScreen";
    import MineScreen from "./index18/MineScreen";
    import TabBarItem from "./index18/TabBarItem";
    export default class MainComponent extends Component {
        render() {
            return (
                <Navigator/>
            );
        }
    }
    const DrawerRouteConfigs = {
        Home: {
            screen: HomeScreen,
            navigationOptions: ({navigation}) => ({
                drawerLabel : '首页',
                drawerIcon : ({focused, tintColor}) => (
                    <TabBarItem
                        tintColor={tintColor}
                        focused={focused}
                        normalImage={require('./img/tabbar/pfb_tabbar_homepage_2x.png')}
                        selectedImage={require('./img/tabbar/pfb_tabbar_homepage_selected_2x.png')}
                    />
                ),
            }),
        },
        NearBy: {
            screen: NearByScreen,
            navigationOptions: {
                drawerLabel : '附近',
                drawerIcon : ({focused, tintColor}) => (
                    <TabBarItem
                        tintColor={tintColor}
                        focused={focused}
                        normalImage={require('./img/tabbar/pfb_tabbar_merchant_2x.png')}
                        selectedImage={require('./img/tabbar/pfb_tabbar_merchant_selected_2x.png')}
                    />
                ),
            },
        },
        Mine: {
            screen: MineScreen,
            navigationOptions: {
                drawerLabel : '我的',
                drawerIcon : ({focused, tintColor}) => (
                    <TabBarItem
                        tintColor={tintColor}
                        focused={focused}
                        normalImage={require('./img/tabbar/pfb_tabbar_mine_2x.png')}
                        selectedImage={require('./img/tabbar/pfb_tabbar_mine_selected_2x.png')}
                    />
                ),
            },
        }
    };
    const DrawerNavigatorConfigs = {
        initialRouteName: 'Home',
        tabBarComponent: TabBarBottom,
        tabBarPosition: 'bottom',
        lazy: true,
        tabBarOptions: {}
    };
    const Drawer = DrawerNavigator(DrawerRouteConfigs, DrawerNavigatorConfigs);
    const StackRouteConfigs = {
        Drawer: {
            screen: Drawer,
        }
    };
    const StackNavigatorConfigs = {
        initialRouteName: 'Drawer',
        navigationOptions: {
            title: '标题',
            headerStyle: {backgroundColor: '#5da8ff'},
            headerTitleStyle: {color: '#333333'},
        }
    };
    const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);

    源码: https://git.oschina.net/xiaojianjun/DD (index20.js、index21.js、index22.js)

    参考

  • 相关阅读:
    vue中使用$router.push跳转新页面
    08、TypeScript 装饰器
    07、TypeScript 命名空间
    06、TypeScript 类型、接口、类、泛型 综合使用,封装一个操作数据库的库
    Java课程总结
    Java第六次上机
    Java第三次上级
    Java第一次上机
    Java第二次实训
    Java第五次上机
  • 原文地址:https://www.cnblogs.com/CrazyWL/p/7283600.html
Copyright © 2011-2022 走看看