react-navigation使用技巧

来源:互联网 发布:狸窝网络视频下载器 编辑:程序博客网 时间:2024/05/17 02:00

http://www.jianshu.com/u/9895046b765d
react-native.jpeg

本文是基于react-navigation^1.0.0-beta.9来书写的。

如果遇到什么问题可以在评论区回复,或者加QQ群397885169讨论

识兔,一款用来识别图片的开源项目,在未来还会添加更多有意思的东西

App.js存放着本文的配置例子

什么是react-navigation?

react-native从开源至今,一直存在几个无法解决的毛病,偶尔就会复发让人隐隐作痛,提醒你用的不是原生,其中包括列表的复用问题,导航跳转不流畅的问题等等。
终于facebook坐不住了,在前一段时间开始推荐使用react-navigation,并且在0.44发布的时将之前一直存在的Navigator废弃了。
react-navigation是致力于解决导航卡顿,数据传递,Tabbar和navigator布局,支持redux。虽然现在功能还不完善,但基本是可以在项目中推荐使用的。

属性

react-navigation分为三个部分。
StackNavigator类似顶部导航条,用来跳转页面和传递参数。
TabNavigator类似底部标签栏,用来区分模块。
DrawerNavigator抽屉,类似从App左侧滑出一个页面,具体我没有使用过,在这里不做讲解。
下面会分开讲解官网提供的配置方法,但顺序可能会官网不一样,因为我认为有些东西可能用不到的只会说一下。

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:设置导航条的样式。背景色,款高等。
  • headerTitleStyle:设置导航条文字样式。
  • headerBackTitleStyle:设置导航条返回文字样式。
  • headerTintColor:设置导航条颜色。总感觉和上面重叠了。
  • headerPressColorAndroid:安卓独有的设置颜色纹理,需要安卓版本大于5.0
  • gesturesEnabled:是否支持滑动返回收拾,iOS默认支持,安卓默认关闭

导航视觉效果

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。推荐这个方式。

标签栏配置

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来暂时解决这个问题。
  • labelStyle:label的样式。
  • iconStyle:图标的样式。
    ps:很多人问我,为什么安卓上的tabbar文字会下移, 是因为安卓比iOS多了一个属性,就是iconStyle,通过设置labelStyleiconStyle两个样式,外加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)=>{}                   });
// 在第二个页面,在goBack之前,将上个页面的方法取到,并回传参数,这样回传的参数会重走render方法state.params.callback(this.state.data);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

早上有人问我,tabbar的图标可不可以使用原图,选中状态下可不可以设置其他图标。研究了一下官方文档,发现tabBarIcon除了tintColor还有另一个属性,用来判断选中状态的focused

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

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

再封装

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(){}中动态的添加点击事件
属性给paramscomponentDidMount(){    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.title,        headerRight:(            <Text onPress={navigation.state.params.navigatePress}>                返回            </Text>        )});

让安卓实现push动画

之前我群里的讨论怎么让安卓实现类似iOS的push动画,后来翻看官方issues的时候,真的发现了实现push动画的代码,在这里共享下

// 先引入这个方法import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';// 在StackNavigator配置headerMode的地方,使用transitionConfig添加{    headerMode: 'screen',    transitionConfig:()=>({        screenInterpolator:CardStackStyleInterpolator.forHorizontal,    })}

总结

react-navigation才开始用的时候感觉是复杂的,但用的多了,会感觉真的很不错。
如果在文章中有什么不懂的问题,欢迎在评论区评论,也可以发私信,加QQ群397885169一起讨论哦。

原创粉丝点击