美文网首页
react-navigation使用技巧

react-navigation使用技巧

作者: 蚊小文 | 来源:发表于2018-03-12 13:23 被阅读0次

    react-navigation简介

    react-navigation是致力于解决导航卡顿,数据传递,Tabbar和navigator布局,支持redux,具有原生般的性能体验效果。可能会成为未来React Native导航组件的主流军。Fb推荐使用库,并且在React Native当前最新版本0.44中将Navigator删除。

    属性

    react-navigation分为三个部分。
    StackNavigator类似顶部导航条,用来跳转页面和传递参数。
    TabNavigator类似底部标签栏,用来在同一屏幕下切换不同界面
    DrawerNavigator抽屉,类似从App左侧滑出一个页面,在这里不做讲解。

    screenProps

    screenProps:react-navigation自带的一个属性,属于navigationOptions的一个属性,可以全局控制navigationOptions中的某些值,比如说你想做换肤功能,修改这个属性绝对是最简单的方式。

    // 假设App就是项目中的入口文件,如果还不知道,可以看下Demo,在这里我将主题色通过screenProps属性修改成'red'
    <App screenProps={{themeColor:'red'}}>
    
    // 在页面中就可以通过screenProps来直接改变了,这个在Demo
    中的Test2里面
    
    static navigationOptions = ({navigation,screenProps}) => ({
            // 这里面的属性和App.js的navigationOptions是一样的。
                    headerStyle:{backgroundColor:screenProps?
                    screenProps.themeColor:
                    '#4ECBFC'},
    
    
        )
    })
    

    StackNavigator 基础用法/属性介绍

    const MyApp = StackNavigator({
        // 对应界面名称
        MyTab: {
            screen: MyTab,
        },
        Detail: {
            screen: Detail,
            navigationOptions:{
                headerTitle:'详情',
                headerBackTitle:null,
            }
        },
    }, {
        headerMode: 'screen',
    });
    

    导航配置

    screen:对应界面名称,需要填入import之后的页面。

    navigationOptions:配置StackNavigator的一些属性。

    • title:标题,如果设置了这个导航栏和标签栏的title就会变成一样的,所以不推荐使用这个方法。
    • header:可以设置一些导航的属性,当然如果想隐藏顶部导航条只要将这个属性设置为null就可以了。
    • headerTitle:设置导航栏标题,推荐用这个方法。
    • headerBackTitle:设置跳转页面左侧返回箭头后面的文字,默认是上一个页面的标题。可以自定义,也可以设置为null
    • headerTruncatedBackTitle:设置当上个页面标题不符合返回箭头后的文字时,默认改成"返回"。(上个页面的标题过长,导致显示不下,所以改成了短一些的。)
    • headerRight:设置导航条右侧。可以是按钮或者其他。
    • headerLeft:设置导航条左侧。可以是按钮或者其他。
    • headerStyle:设置导航条的样式。背景色,宽高等。如果想去掉安卓导航条底部阴影可以添加elevation: 0,iOS下用shadowOpacity: 0。
    • headerTitleStyle:设置导航条文字样式。安卓上如果要设置文字居中,只要添加alignSelf:'center'就可以了。在安卓上会遇到,如果左边有返回箭头导致文字还是没有居中的问题,最简单的解决思路就是在右边也放置一个空的按钮。
    • headerBackTitleStyle:设置导航条返回文字样式。
    • headerTintColor:设置导航栏文字颜色。总感觉和上面重叠了。
    • headerPressColorAndroid:安卓独有的设置颜色纹理,需要安卓版本大于5.0
    • gesturesEnabled:是否支持滑动返回手势,iOS默认支持,安卓默认关闭
    • gestureResponseDistance:对象覆盖触摸从屏幕边缘开始的距离,以识别手势。 它需要以下属性:
    • horizontal - number - 水平方向的距离 默认为25。
    • vertical - number - 垂直方向的距离 默认为135。
    // 设置滑动返回的距离
    gestureResponseDistance:{horizontal:300},
    

    导航视觉效果

    • mode:定义跳转风格。

    • card:使用iOS和安卓默认的风格。

    • modal:iOS独有的使屏幕从底部画出。类似iOS的present效果

    • headerMode:边缘滑动返回上级页面时动画效果。

    • float:iOS默认的效果,可以看到一个明显的过渡动画。

    • screen:滑动过程中,整个页面都会返回。

    • none:没有动画。

    • cardStyle:自定义设置跳转效果。

    • transitionConfig: 自定义设置滑动返回的配置。

    • onTransitionStart:当转换动画即将开始时被调用的功能。

    • onTransitionEnd:当转换动画完成,将被调用的功能。

    • path:路由中设置的路径的覆盖映射配置。

    • initialRouteName:设置默认的页面组件,必须是上面已注册的页面组件。

    • initialRouteParams:初始路由的参数。

    • path:path属性适用于其他app或浏览器使用url打开本app并进入指定页面。path属性用于声明一个界面路径,例如:【/pages/Home】。此时我们可以在手机浏览器中输入:app名称://pages/Home来启动该App,并进入Home界面。

    TabNavigator 基础用法/属性介绍

    const MyTab = TabNavigator({
        ShiTu: {
            screen: ShiTu,
            navigationOptions:{
                tabBarLabel: '内容',
                tabBarIcon: ({tintColor}) => (
                    <Image
                        source={{uri : '内容'}}
                        style={[tabBarIcon, {tintColor: tintColor}]}
                    />
                ),
            },
        }, {
        tabBarPosition: 'bottom',
        swipeEnabled:false,
        animationEnabled:false,
        tabBarOptions: {
            style: {
                height:49
            },
            activeBackgroundColor:'white',
            activeTintColor:'#4ECBFC',
            inactiveBackgroundColor:'white',
            inactiveTintColor:'#aaa',
            showLabel:false,
        }
    });
    

    屏幕导航配置

    • screen:和导航的功能是一样的,对应界面名称,可以在其他页面通过这个screen传值和跳转。

    • navigationOptions:配置TabNavigator的一些属性

    • title:标题,会同时设置导航条和标签栏的title,还是不推荐这种方式。

    • tabBarVisible:是否隐藏标签栏。默认不隐藏(true)

    • tabBarIcon:设置标签栏的图标。需要给每个都设置。

    • tabBarLabel:设置标签栏的title。推荐这个方式。

    • tabBarOnPress:设置tabBar的点击事件,内部提供了两个属性,一个方法(obj)。

    • beta13新添加的方法,使用方式有些奇葩,如果想要使用,请参照下面的代码

    tabBarOnPress:(obj)=>{
                console.log(obj);
    
                obj.jumpToIndex(obj.scene.index)
            },
    

    标签栏配置

    • tabBarPosition:设置tabbar的位置,iOS默认在底部,安卓默认在顶部。(属性值:'top','bottom')

    • swipeEnabled:是否允许在标签之间进行滑动。

    • animationEnabled:是否在更改标签时显示动画。

    • lazy:是否根据需要懒惰呈现标签,而不是提前制作,意思是在app打开的时候将底部标签栏全部加载,默认false,推荐改成true哦。

    • initialRouteName: 设置默认的页面组件

    • backBehavior:按 back 键是否跳转到第一个Tab(首页), none 为不跳转

    • tabBarOptions:配置标签栏的一些属性

    iOS属性

    • activeTintColor:label和icon的前景色 活跃状态下(选中)。
    • activeBackgroundColor:label和icon的背景色 活跃状态下(选中) 。
    • inactiveTintColor:label和icon的前景色 不活跃状态下(未选中)。
    • inactiveBackgroundColor:label和icon的背景色 不活跃状态下(未选中)。
    • showLabel:是否显示label,默认开启。
    • style:tabbar的样式。
    • labelStyle:label的样式。

    安卓属性

    • activeTintColor:label和icon的前景色 活跃状态下(选中) 。
    • inactiveTintColor:label和icon的前景色 不活跃状态下(未选中)。
    • showIcon:是否显示图标,默认关闭。
    • showLabel:是否显示label,默认开启。
    • style:tabbar的样式。
    • labelStyle:label的样式。
    • upperCaseLabel:是否使标签大写,默认为true。
    • pressColor:material涟漪效果的颜色(安卓版本需要大于5.0)。
    • pressOpacity:按压标签的透明度变化(安卓版本需要小于5.0)。
    • scrollEnabled:是否启用可滚动选项卡。
    • tabStyle:tab的样式。
    • indicatorStyle:标签指示器的样式对象(选项卡底部的行)。安卓底部会多出一条线,可以将height设置为0来暂时解决这个问题。
    • iconStyle:图标的样式。
      ps:安卓上的tabbar文字会下移, 是因为安卓比iOS多了一个属性,就是iconStyle,通过设置labelStyle和iconStyle两个样式,外加style的高度,来使效果更佳合理.

    跳转

    navigate('Detail',{
                       title:'图片详情',
                       url:item.url,
                       });
    

    Detail:在StackNavigator中注册的页面,需要一一对应,才能跳转到相应的页面
    title:在跳转的页面可以通过this.props.navigation.state.params.title获取到这个参数。当然这个参数可以随便填写,都可以通过this.props.navigation.state.params.xxx获取。

    回调传参

    navigate('Detail',{
                       // 跳转的时候携带一个参数去下个页面
                       callback: (data)=>{
                             console.log(data); // 打印值为:'回调参数'
                         }
                       });
    const {navigate,goBack,state} = this.props.navigation;
    // 在第二个页面,在goBack之前,将上个页面的方法取到,并回传参数,这样回传的参数会重走render方法
    state.params.callback('回调参数');
    goBack();
    

    自定义

    项目中基本是没可能用自带的那个导航条的,自带导航条左侧的按钮永远是蓝色的,如果我们需要更改按钮颜色,就需要用到自定义的功能了。

    const StackOptions = ({navigation}) => {
        console.log(navigation);
        let {state,goBack} = navigation;
        
        // 用来判断是否隐藏或显示header
        const visible= state.params.isVisible;
        let header;
        if (visible === true){
            header = null;
        }
        const headerStyle = {backgroundColor:'#4ECBFC'};
        const headerTitle = state.params.title;
        const headerTitleStyle = {fontSize:FONT_SIZE(20),color:'white',fontWeight:'500'}
        const headerBackTitle = false;
        const headerLeft = (
            <Button
                isCustom={true}
                customView={
                                <Icon
                                    name='ios-arrow-back'
                                    size={30}
                                    color='white'
                                    style={{marginLeft:13}}
                                />
                            }
                onPress={()=>{goBack()}}
            />
        );
        return {headerStyle,headerTitle,headerTitleStyle,headerBackTitle,headerLeft,header}
    };
    

    然后通过下面的方法调用就可以自定制导航了。

    const MyApp = StackNavigator({
        MyTab: {
            screen: MyTab,
        },
        Detail: {
            screen: Detail,
            navigationOptions: ({navigation}) => StackOptions({navigation})
        },
    )};
    

    在页面中使用的时候,在跳转页面的时候需要传递title参数,才能看到效果哦。

    自定义tabbar

    tabBarIcon除了tintColor还有另一个属性,用来判断选中状态的focused。

     tabBarIcon: ({tintColor,focused}) => (
                    focused
                        ?
                        <Image
                            source={{uri : '识兔'}}
                            style={tabBarIcon}
                        />
                        :
                        <Image
                            source={{uri : '干货'}}
                            style={[tabBarIcon, {tintColor: tintColor}]}
                        />
                ),
    

    通过判断focused,选中状态下使用识兔图标,未选中状态使用干货图标。
    如果想使用图标原来的样子,那就将style的tintColor去掉,这样就会显示图标原本的颜色。

    再封装

    export const TabOptions = (tabBarTitle,normalImage,selectedImage,navTitle) => {
        // console.log(navigation);
        const tabBarLabel = tabBarTitle;
        console.log(navTitle);
        const tabBarIcon = (({tintColor,focused})=> {
            return(
                focused
                    ?
                    <Image
                        source={{uri : normalImage}}
                        style={[TabBarIcon, {tintColor: tintColor}]}
                    />
                    :
                    <Image
                        source={{uri : selectedImage}}
                        style={[TabBarIcon, {tintColor: tintColor}]}
                    />
            )
        });
        const headerTitle = navTitle;
        const headerTitleStyle = {fontSize:FONT_SIZE(20),color:'white'};
        // header的style
        const headerStyle = {backgroundColor:'#4ECBFC'};
        return {tabBarLabel,tabBarIcon,headerTitle,headerTitleStyle,headerStyle};
    };
    

    在static中使用this方法

    我之前文章中是将navaigationOptions的方法写在了app.js中,没有在页面中通过static navaigationOptions来初始化页面,这段时间刚好有人问,所以在这里就写一下该怎么弄。

    首先需要在componentDidMount(){}中动态的添加点击事件
    属性给params

    componentDidMount(){
    
        this.props.navigation.setParams({
            title:'自定义Header',
            navigatePress:this.navigatePress
        })
    }
    navigatePress = () => {
        alert('点击headerRight');
        console.log(this.props.navigation);
    }
    

    接下来就可以通过params方法来获取点击事件了

    static navigationOptions = ({ navigation, screenProps }) => ({
            title: navigation.state.params?navigation.state.params.title:null,
            headerRight:(
                <Text onPress={navigation.state.params?navigation.state.params.navigatePress:null}>
                    返回
                </Text>
            )
    });
    

    相关文章

      网友评论

          本文标题:react-navigation使用技巧

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